-2

I will take an exam and my teacher asks weird C syntax rules. Like:

int q=5;  
for(q=-2;q=-5;q+=3) { //assignment in condition part??     
    printf("%d",q);      //prints -5  
    break;     
} 

Or

int d[][3][2]={4,5,6,7,8,9,10,11,12,13,14,15,16};     
int i=-1;     
int j;     
j=d[i++][++i][++i];   
printf("%d",j); //prints 4?? why j=d[0][0][0] ?

Or

extern int a; 
int main() {     
    do {         
        do {              
            printf("%o",a); //prints 12         
        } while(!1);     
    } while(0);  
    return 0; 
} 
int a=10;

I could not find it rules any site or book. Really absurd and uncommon. Where can I find?

Christian Gibbons
  • 4,272
  • 1
  • 16
  • 29
array
  • 1
  • Meh, many teachers do ask stupid things and with even worse formatting so as to confuse you. – DeiDei May 08 '18 at 14:30
  • @Badiparmagi because the students should think about what they learn and apply the rules accordingly. It doesn't have to make any sense or be useful. – Gerhardh May 08 '18 at 14:44
  • To be a bit nitpicking, your question is more related to semantics, not to syntax of C. – Gerhardh May 08 '18 at 14:48
  • 1
    Off topic: it is about us asking to recommend an off-site resource (book, external website, teacher's comment). It tends to attract opinion-based answers. – Ṃųỻịgǻňạcểơửṩ May 08 '18 at 17:16

3 Answers3

2

Concerning for(q=-2;q=-5;q+=3) {, all you need to do is to break this down into its components. q=-2 is ran first, then q=-5 is tested, and if that is not 0 (which it isn't since it's an expression with value -5), then the loop body runs once. Then break forces a premature exit from an otherwise infinite loop. The expression then q+=3 is never reached.

The behaviour of d[i++][++i][++i] is undefined. Tell your teacher that, tactfully.

The "%o" format denotes octal output. a is set to 10 in decimal which is 12 in octal. Your code would be clearer if you had written:

int a=012; // octal constant.
Bathsheba
  • 231,907
  • 34
  • 361
  • 483
2

To me it seems that your teacher is asking questions which invole undefined behavior.

If you tell him that this is incorrect, you're directly confronting him.

However, you could do the following:

  1. Compile the code on different platforms
  2. Compile the code with different compilers
  3. Compile the code with different versions of the same compiler
  4. Build a matrix with the results. You'll find out that they differ
  5. Show the results to your teacher ans ask him to explain why that happens

That way you do not say that he's wrong, you're just showing some facts and you're showing that you're willing to learn and work.

Do that a long before the exam so that the teacher can look into it and think about his questions so that he can change the exam in time.

I could not find it rules any site or book. Where can I find?

See Where do I find the current C or C++ standard documents?. If you have a good library at university, they should own a copy.

Thomas Weller
  • 55,411
  • 20
  • 125
  • 222
  • On the different platforms, note that MSVC will increment `i` at the end of the statement, and gcc increments `i` prior to the assignment; I think ;-) Nice answer, upped. – Bathsheba May 08 '18 at 14:39
1

The online version of the C language standard has what you need (and is what I will be referring to in this answer); just bear in mind is is a language definition and not a tutorial, and as such may not be easy to read for someone who doesn't have a lot of experience yet.

Having said that, your teacher is throwing you a few foul balls. For example:

j=d[i++][++i][++i];   

This statement results in undefined behavior for several reasons. The first several paragraphs of section 6.5 of the document linked above explain the problem, but in a nutshell:

  • Except in a few situations, C does not guarantee left-to-right evaluation of expressions; neither does it guarantee that side effects are applied immediately after evaluation;

  • Attempting to modify the value of an object more than once between sequence points1, or modifying and then trying to use the value of an object without an intervening sequence point, results in undefined behavior.

Basically, don't write anything of the form:

x = x++;
x++ * x++;
a[i] = i++;
a[i++] = i;

C does not guarantee that each ++i and i++ is evaluated from left to right, and it does not guarantee that the side effect of each evaluation is applied immediately. So the result of j[i++][++i][++i] is not well-defined, and the result will not be consistent over different programs, or even different builds of the same program2.

AND, on top of that, i++ evaluates to the current value of i; so clearly, your teacher's intent was for j[i++][++i][++i] to evaluate to j[-1][1][2], which would also result in undefined behavior since you're attempting to index outside of the array bounds.

This is why I hate, hate, hate it when teachers throw this kind of code at their students - not only is it needlessly confusing, not only does it encourage bad practice, but more often than not it's just plain wrong.

As for the other questions:

for(q=-2;q=-5;q+=3) { //assignment in condition part?? 

See sections 6.5.16 and 6.8.5.3. In short, an assignment expression has a value (the value of the left operand after any type conversions), and it can appear as part of a controlling expression in a for loop. As long as the result of the assignment is non-zero (as in the case above), the loop will execute.

printf("%o",a); //prints 12         

See section 7.21.6.1. The o conversion specifier tells printf to format the integer value as octal: 1010 == 128


  1. A sequence point is a point in a programs execution where an expression has been fully evaluated and any side effects have been applied. Sequence points occur at the ends of statements, between the evaluation of a function's parameters and the function call, after evaluating the left operand of the &&, ||, and ?: operators, and a few other places. See Annex C for the complete list.
  2. Or even different runs of the same build, although in practice you won't see values change from run to run unless you're doing something really hinky.

John Bode
  • 119,563
  • 19
  • 122
  • 198