4

I have a bit of sample code that is throwing this warning:

main.c: In function ‘getline_’:
main.c:30:32: warning: operation on ‘c’ may be undefined [-Wsequence-point]

In this particular exercise I was to avoid using the || and && operator, but this doesn't seem like it should produce undefined behavior. The compiler message is just a warning, but I wanted to know for knowings sake. Is this code actually going to produce undefined behavior?

 24 int getline_( char s[], int limit)
 25 {
 26     int i, c;
 27     i=0;
 28     for( i=0; (i<limit-1) + ((c=getchar())!='\n') + (c!=EOF) == 3; i++){
 29            s[i]=c;
 30     }
 31     if( c == '\n' ){
 32         s[i]=c;
 33         i++;
 34     }
 35     s[i]='\0';
 36     return i;
 37 }

It seems to work ok in my basic tests.

Edit: Updated title as per comment, thanks pst.

Jeff Welling
  • 1,625
  • 2
  • 13
  • 17
  • 3
    Just because "it works here" doesn't mean it's *defined* behavior. The *UB* might be the behavior that you've always observed... (it could involve flying hamsters somewhere else, though) –  Jun 23 '12 at 19:06
  • 1
    Which is exactly why I wanted to know for sure, and came here. :) – Jeff Welling Jun 23 '12 at 19:07
  • 1
    Consider distilling the test-case (a warning can be generated with far less) and incorporating that into the title. It basically comes down to: `(c=x) + (c==y)` –  Jun 23 '12 at 19:08
  • probable duplicate of http://stackoverflow.com/questions/949433/could-anyone-explain-these-undefined-behaviors-i-i-i-i-i-etc/16787634#16787634 – hanish May 30 '13 at 08:16

1 Answers1

13

This is unspecified behavior:

(i<limit-1) + ((c=getchar())!='\n') + (c!=EOF) == 3

the order of evaluation of expressions between sequence points is unspecified in C. It is unspecified if the assignment to c occurs before the equality check with EOF.

In addition to the unspecified behavior, it is also undefined behavior because it violates the sequence points rules and particularly this one:

(C99, 6.5p2) "Furthermore, the prior value shall be read only to determine the value to be stored."

ouah
  • 142,963
  • 15
  • 272
  • 331
  • 2
    Pedantic nitpick: But the warning say its Undefined Behavior not Unspecified Behavior, So... – Alok Save Jun 23 '12 at 19:15
  • Note to self, needs a dash of lisp. Thanks for pointing that out! Just waiting for the timer to vanish to accept... – Jeff Welling Jun 23 '12 at 19:15
  • So, am I correct in interpreting that sequence point rule to mean that it is invalid to have a variable assignment in that expression? Sorry if it seems like another silly question, c novice here... – Jeff Welling Jun 23 '12 at 19:19
  • Congrats because What you think is indeed correct :) and that is what the answer should say to beginwith. – Alok Save Jun 23 '12 at 19:19
  • It's not just unspecified; it's undefined. Because `c` is both written and read between sequence points and the value read is used for a purpose other than determining the value to be written, it's UB. – R.. GitHub STOP HELPING ICE Jun 23 '12 at 19:20