Rohit Chauhan
Rohit Chauhan

Reputation: 61

Why does the following code give different results when compiling with gcc and g++?

#include<stdio.h>
int main()
{
    const int a=1;
    int *p=(int *)&a;
    (*p)++;
    printf("%d %d\n",*p,a);
    if(a==1)
      printf("No\n");//"No" in g++.
    else
      printf("Yes\n");//"Yes" in gcc.
    return 0;
}

The above code gives No as output in g++ compilation and Yes in gcc compilation. Can anybody please explain the reason behind this?

Upvotes: 3

Views: 1295

Answers (4)

user3710044
user3710044

Reputation: 2334

Okay we have here 'identical' code passed to "the same" compiler but once with a C flag and the other time with a C++ flag. As far as any reasonable user is concerned nothing has changed. The code should be interpreted identically by the compiler because nothing significant has happened.

Actually, that's not true. While I would be hard pressed to point to it in a standard but the precise interpretation of 'const' has slight differences between C and C++. In C it's very much an add-on, the 'const' flag says that this normal variable 'a' should not be written to by the code round here. But there is a possibility that it will be written to elsewhere. With C++ the emphasis is much more to the immutable constant concept and the compiler knows that this constant is more akin to an 'enum' that a normal variable.

So I expect this slight difference means that slightly different parse trees are generated which eventually leads to different assembler.

This sort of thing is actually fairly common, code that's in the C/C++ subset does not always compile to exactly the same assembler even with 'the same' compiler. It tends to be caused by other language features meaning that there are some things you can't prove about the code right now in one of the languages but it's okay in the other.

Usually C is the performance winner (as was re-discovered by the Linux kernel devs) because it's a simpler language but in this example, C++ would probably turn out faster (unless the C dev switches to a macro or enum and catches the unreasonable act of taking the address of an immutable constant).

Upvotes: 1

juanchopanza
juanchopanza

Reputation: 227400

Your code triggers undefined behaviour because you are modifying a const object (a). It doesn't have to produce any particular result, not even on the same platform, with the same compiler.

Although the exact mechanism for this behaviour isn't specified, you may be able to figure out what is happening in your particular case by examining the assembly produced by the code (you can see that by using the -S flag.) Note that compilers are allowed to make aggressive optimizations by assuming code with well defined behaviour. For instance, a could simply be replaced by 1 wherever it is used.

Upvotes: 10

Sourav Ghosh
Sourav Ghosh

Reputation: 134326

In your code, notice following two lines

const int a=1;        // a is of type constant int
int *p=(int *)&a;     // p is of type int *

you are putting the address of a const int variable to an int * and then trying to modify the value, which should have been treated as const. This is not allowed and invokes undefined behaviour.

For your reference, as mentioned in chapter 6.7.3, C11 standard, paragraph 6

If an attempt is made to modify an object defined with a const-qualified type through use of an lvalue with non-const-qualified type, the behavior is undefined. If an attempt is made to refer to an object defined with a volatile-qualified type through use of an lvalue with non-volatile-qualified type, the behavior is undefined

So, to cut the long story short, you cannot rely on the outputs for comaprison. They are the result of undefined behaviour.

Upvotes: 4

Vlad from Moscow
Vlad from Moscow

Reputation: 310980

From the C++ Standard (1.9 Program execution)

4 Certain other operations are described in this International Standard as undefined (for example, the effect of attempting to modify a const object). [ Note: This International Standard imposes no requirements on the behavior of programs that contain undefined behavior. —end note ]

Thus your program has undefined behaviour.

Upvotes: 6

Related Questions