0

I have written this little parser that reads in some numbers from text file.

    data.resize(7,datapoints); //Eigen::Matrix<float,7,-1> & data
    dst = data.data();

    while( fgets(buf,255,fp) != 0 && i/7 < datapoints)
    {

        int n = sscanf(buf,"%f \t%f \t%f \t%f \t%f \t%f \t%f",dst+i++, dst+i++,dst+i++,dst+i++,dst+i++,dst+i++,dst+i++);
            i = i - 7 * (n<=0);
    }
    fclose(fp);
    return !(datapoints == i/7);

The thing is, when i do a std::cout on the data it flipped.

Data in:

0   4   0.35763609  0.64077979  0   0   1
0   4   0.36267641  0.68243247  1   0   2
0   4   0.37477320  0.72945964  2   1   3

data.col(3) is

0.64077979  
0.68243247  
0.72945964 

and data.col(4) is

0.35763609  
0.36267641  
0.37477320 

I cant see the logic why it have flipped the data horizontal?

qPCR4vir
  • 3,521
  • 1
  • 22
  • 32
Poul K. Sørensen
  • 16,950
  • 21
  • 126
  • 283

2 Answers2

6

To illustrate the problem:

#include <cstdio>

void f(int i, int j, int k)
{
  printf("i = %d\tj = %d\tk = %d\n", i, j, k);
}

int main()
{
  int i=0;
  f(i++, i++, i++);
}

Executing this, returns here (g++ 4.3.4 on Cygwin):

i = 2   j = 1   k = 0

The execution order of the i++ calls inside the function call is entirely implementation defined (i.e. arbitrary).

Michael Wild
  • 24,977
  • 3
  • 43
  • 43
  • hmm, guess you learn something new everyday. Would love a comment on why and why it is not made such they are evaluated in same order as parsed. – Poul K. Sørensen Jan 28 '13 at 11:45
  • 2
    Ask google or see here: http://stackoverflow.com/questions/2934904/order-of-evaluation-in-c-function-parameters – Michael Wild Jan 28 '13 at 11:47
  • Should i understand it as the first %f in the format string can be copied into any of the arguments at the end? or just that the code on each argument position can be evaluated in any order? – Poul K. Sørensen Jan 28 '13 at 12:00
  • The order in which the various `i++` calls are made is undefined. This means that the fields of the `fscanf` call can be shuffled in any order. – Michael Wild Jan 28 '13 at 12:05
3

Are you sure than?

int i=0;
sscanf(buf,"%f \t%f \t%f \t%f \t%f \t%f \t%f",dst+i++, dst+i++,dst+i++,dst+i++,dst+i++,dst+i++,dst+i++);

is equal to:

sscanf(buf,"%f \t%f \t%f \t%f \t%f \t%f \t%f",dst+0,dst+1,dst+2,dst+3,dst+4,dst+5,dst+6 );

I think the variable list arg is geting evaluated back in this case, and as @Christian Rau comment in general is Undefined the order of evaluation. Oft it is not a good idea to realy on side -effect order.

qPCR4vir
  • 3,521
  • 1
  • 22
  • 32
  • Yest, i = 0 at the beginning. – Poul K. Sørensen Jan 28 '13 at 11:37
  • 2
    *"I think the variable list arg get evaluated back"* - No, it isn't. It is evaluated in an undefined order, which is why his code could in the end produce any output possible. Though, you're on the right track with this code line, because of exactly this undefined evaluation order. – Christian Rau Jan 28 '13 at 11:38
  • What? you saying that the first %f do not map to the first argument after the format string ? – Poul K. Sørensen Jan 28 '13 at 11:40
  • 1
    @s093294: No he is saying, that the order in which the function parameters are calculated is not determined. It could lead to any behaviour like this: `sscanf("...", dst + 3, dst + 1, dst + 4, dst + 2, dst + 0)` or like in your case to inversed order. – Nobody moving away from SE Jan 28 '13 at 11:43
  • 1
    @s093294 Of course the first `%` maps to the first function argument, but that doesn't neccessarily mean those function arguments are computed in this order. Imagine your compiler computing all those function arguments into temporary variables, and this in a totally undefined order. It then calls the function with those computed results. – Christian Rau Jan 28 '13 at 14:45