Arguments are reversed for function C

I have a function that multiplies two matrices A and B and then prints the result. I got two different outputs when starting the program in two ways.

first:

FILE *f; f = fopen("in.txt","r"); struct Mat* A = read_mat(f); struct Mat* B = read_mat(f); print_mat(mat_mul_1(A, B)); 

the output was exact multiplication

A * b

second:

  FILE *f; f = fopen("in.txt","r"); print_mat(mat_mul_1(read_mat(f), read_mat(f))); 

the output was exact multiplication

B * a

I want to know why the arguments were reversed ?!

(since the function "mat_mul_1" is a black box)

+6
source share
5 answers

Did you expect the first read_mat(f) be evaluated first?

C does not offer such guarantees. The compiler is free to emit code that evaluates the arguments in any order that it chooses.

The order of evaluation of the function pointer, the actual arguments and the subexpressions in the actual arguments are not defined, but there is a sequence point before the actual call.

+8
source

The reason others have already indicated that the order in which functional parameters are evaluated is unspecified behavior, and therefore should not be relied upon. But there is another, possibly serious problem:

The read_mat function can access static resources, such as static / global variables, and then return their values. Like this:

 static int x; int inc (void) { x++; return x; } printf("%d %d", inc(), inc()); 

The actual result of the function will depend on the evaluation order.

(This snippet is taken from an interview test that I use when hiring C programmers. I ask what the output of this code is and the correct answer is β€œ2 1” or β€œ1 2”. The question checks if the C programmer knows the concepts are static initialization and evaluation procedure.)

+2
source

This is due to the order parameters for the function being evaluated:

 print_mat(mat_mul_1(A, B)); 

will call mat_mul_1(A, B) , where A is the first matrix in the file and B is the second. In your second case:

 print_mat(mat_mul_1(read_mat(f), read_mat(f))); 

I assume (because it is not specified by the standard) that on your system first calls the second read_mat() and thus calls mat_mul_1(B, A);

0
source

The reason is that the rightmost read_mat(f) is called before the leftmost, and so you are reading the first structure in what you would assume as B Therefore, A and B are reversed.

I kind of understand this in that the arguments are pushed onto the stack in the reverse order when they are passed to the function, so they are evaluated from right to left.

I am not sure if there is any standard that defines what should be evaluated first.

0
source

There is undefined behavior in your code because the FILE pointed to by f changes both the first and second read_mat(f) , and there is no sequence point between the two changes.

0
source

Source: https://habr.com/ru/post/901092/


All Articles