3

I'm curious about this code:

int a = 'ftyp';          // a == 1718909296
int b = *((int*)"ftyp"); // b == 1887007846

My question: Why a != b ?

codeDom
  • 1,623
  • 18
  • 54

1 Answers1

8
int a = 'ftyp';          // a == 1718909296

sets a to the multi-character constant, which has implementation defined value. The value of a is not defined by the standard. See Single quotes vs. double quotes in C or C++ for more details.

int b = *((int*)"ftyp"); // b == 1887007846

is cause for undefined behavior due to violation of strict aliasing.

The expectation that a == b is ill founded.

Community
  • 1
  • 1
R Sahu
  • 204,454
  • 14
  • 159
  • 270
  • 1
    No, the problem here is not aliasing. Aliasing only would be a problem if an object that is aliased would be modified. Then the compiler could make a false assumption that the object that it see through a pointer hasn't changed. The real problem here is possible mis-alignment. – Jens Gustedt Jul 02 '16 at 20:24
  • @JensGustedt Is behavior not undefined if you don't use compatible objects. – 2501 Jul 02 '16 at 20:36
  • @JensGustedt, From C+11 Standard 3.10/10: *If a program attempts to access the stored value of an object through a glvalue of other than one of the following types the behavior is undefined*. None of the clauses that follow allow to access the value of a string literal through a `int*`. – R Sahu Jul 03 '16 at 01:34
  • Citing the C spec rather than C++ for a C language issue would be more convincing. I do not see that the C++ cite supports that is this an aliasing, even thought it is UB for the aliment issue of [@Jens Gustedt](http://stackoverflow.com/questions/38163949/c-single-quotes-vs-double-quotes#comment63756279_38163972). – chux - Reinstate Monica Jul 03 '16 at 04:50
  • @chux, fair enough. From C99 Standard 6.5/7: *An object shall have its stored value accessed only by an lvalue expression that has one of the following types:* More from that section is cited at http://stackoverflow.com/a/7005988/434551. – R Sahu Jul 03 '16 at 04:58
  • Hmmmm, It appears OP's problem is a violation of _strict aliasing_ as it does not meet C11 §6.5 7. OP's code appears also to violate 3.2 1 alignment: ... objects of a particular type be located on storage boundaries with addresses that are particular multiples of a byte address". So UB for 2 reasons: aliasing and alignment? – chux - Reinstate Monica Jul 03 '16 at 05:18
  • @chux, I don't think the alignment violation applies here since the OP is not even constructing an object of type `int`. – R Sahu Jul 03 '16 at 05:28
  • OP is attempting to de-reference an `int*` converted from a `char *` with `int b = *((int*)"ftyp")`. So on systems that allowed that pointer conversion, may still fail the `*(int_pointer)` due to alignment violation. – chux - Reinstate Monica Jul 03 '16 at 05:41
  • @chux, I suspect 3.2/1 controls how members of a `struct` are aligned and padding between such members. I don't think it applies here. – R Sahu Jul 03 '16 at 05:57