-1

Because this is a common error message, I've Googled the issue. Unfortunately, all I could find were threads wherein the issue arose from global and local variables having the same name. My problem has nothing to do with global variables, so I believe this constitutes a new question. C won't let me call a function. Every time I call a function like so

...
adjusted_scores = *new_scores(scores,days_late,penalty);
numeric_score = final_score(adjusted_scores, weights);
...

, with supporting code

int * new_scores(int scores[], int days_late[], int penalty) {
  int new_scores[MAX_ASSIGNMENTS];

  /*computes size of array*/
  int size = sizeof(scores)/sizeof(scores[0]);
  int i;
  for(i=0;i<size;i++){
    new_scores[i]=scores[i]-penalty*days_late[i];
  }
  return new_scores;
}

for the function in question if that helps, I get the message

error: incompatible types when assigning to type 'int[50]' from type 'int'.

Earlier, I had gotten the message

error: called object 'new_scores' is not a function,

so the error message has become longer and the situation has not improved. On top of that, I have been consistently been warned via the message

warning: function returns address of local variable [enabled by default],

so even if I got the errors to vanish, the program would probably mess up in a different way when it came time to actually run the code. Best case scenario is that the code successfully compiles, but whatever the function returns cannot be accessed.

Disclaimer: For unexplained reasons, malloc, memcpy, and any tools related to dynamic memory allocation must not be used to fix the problem. I will try to figure what those reasons are if the disclaimer becomes too much of a burden to deal with.

Display name
  • 257
  • 2
  • 8
  • 1
    (a) You should provide a [mre]. (b) `adjusted_scores` is an array of 50 `int`, and C does not support assigning to an array (just to elements). (c) The parameter `scores`, which is declared as an array, is automatically adjusted to be a pointer. Calculating its size with `sizeof` gives the size of the pointer, not the array. – Eric Postpischil Feb 09 '20 at 02:39
  • When used a parameter, `int scores[]` means `int *scores`. As such, `sizeof(scores)/sizeof(scores[0])` won't work as expected. You will need to pass in that value as an argument. – ikegami Feb 09 '20 at 02:39
  • Essentially, you cannot do this assignment by treating arrays as objects. You need to redesign the code to work on array elements using pointers. – Eric Postpischil Feb 09 '20 at 02:40
  • Re "*tools related to dynamic memory allocation must not be used*", What you do is place `int new_scores[MAX_ASSIGNMENTS]` is in the caller and pass it in as an argument. Turns out you've already created this variable as `adjusted_scores`, so that's what you'd pass in as an argument. – ikegami Feb 09 '20 at 02:40
  • Why did you tag this with c89? Are you using a 30-year-old compiler? – Eric Postpischil Feb 09 '20 at 02:41
  • @EricPostpischil Yes. I've been forced to by a draconian project checker. More precisely, the code needs to work with c89 because otherwise it will not work when I pass it to the checker. – Display name Feb 09 '20 at 02:42

1 Answers1

3

This error message:

error: incompatible types when assigning to type 'int[50]' from type 'int'.

Tells us that adjusted_scores is an array, and you can't assign directly to an array.

This warning:

warning: function returns address of local variable [enabled by default],

Happens because the variable new_scores inside the function new_scores is an array, and an array in most contexts decays into a pointer to its first element, which means you're returning the address of a local variable. This is bad because that variable going out of scope when the function exits rendering the pointer invalid.

The way to fix both of these issues is to pass adjusted_scores to the function and assign the updated values directly to it.

Also, sizeof(scores)/sizeof(scores[0]) won't do what you expect because scores is a pointer, not an array, so sizeof(scores) is the size of a pointer.

So new_scores would look like this:

void new_scores(int result[], int scores[], int size, int days_late[], int penalty) {
  int i;
  for(i=0;i<size;i++){
    result[i]=scores[i]-penalty*days_late[i];
  }
}

And you would call it like this:

new_scores(adjusted_scores,scores,sizeof(scores)/sizeof(scores[0]),days_late,penalty);
dbush
  • 205,898
  • 23
  • 218
  • 273
  • I hope the notion that lines of code in the form x=f(...) where f is a function and x is a variable have to be rewritten isn't an overarching phenomenon in C. Thinking ahead to the future when I will have to create more complicated projects, it seems like the main method will grow larger and larger, the variables at the top of the main method will start taking up tons of lines, and functions will contain tons of parameters that would not be necessary in other languages. Hopefully, I will learn more information before that point to sidestep the looming problem. – Display name Feb 09 '20 at 02:58