
Code behaving differently in C90, C99, C11, C++98, and C++11 - Kristine1975
http://kristerw.blogspot.com/2016/07/code-behaving-differently-in-c90-c99.html
======
pcwalton
I think this goes to show that _theoretical_ backwards compatibility doesn't
matter nearly as much as _de facto_ backwards compatibility. As this IOCCC
entry shows, every single C++ revision has been a breaking change to the
previous revision. A naive interpretation of this would say "well, C++ is not
useful for enterprise use because the language is constantly changing". But in
reality it doesn't matter, because the backwards-incompatible parts affect
code nobody would intentionally write (excluding IOCCC entries!), and as a
result C++ has a deserved reputation for stability.

~~~
vmarsy
> As this IOCCC entry shows, every single C++ revision has been a breaking
> change to the previous revision

This post _never_ mentions C++'s backwards compatibility. It points out these
3 examples:

    
    
      // comments
      C90 does not have // comments, so constructs of the form 

...

i.e. more recent version of C and C++ is a super set of C90 here, but writing
valid C90 (without using // comments), would compile file in C90 and above.

    
    
      Wide string literals
      C11 and C++11 have wide string literals where for example U"hello!"
    

Same reasoning for these, you would never use U"hello!" in pre C11/C++11.

The 3rd example is a fundamental difference between C and C++:

    
    
      Character constants, such as 'a', have type int in C while C++ use the type char. This means that sizeof('a') evaluates to a different value for C and C++.
    
    
    

This is not about backward compatibility, backward compatibility means : your
code written in C++98, still works if compiled in C++11, it does not say :
"write code using newer C++98/11/.../ and try to compile it in a previous
version (or a different language) and see what happens."

To an extreme it's like saying:

    
    
      template<class A>
      struct foo {
        // some methods with use of lambda, variadic templates, ...
      };
    

" _Hey look, the above example doesn 't work with C++98, C++ backward
compatibility is a myth!_"

~~~
chx
You contradict yourself:

> backward compatibility means your code written in C++98, still works if
> compiled in C++11

> writing valid C90 (without using // comments), would compile file in C90 and
> above.

Aye. There's the rub: backwards compatibility _is_ broken by introducing // as
int i = 2 // __* __* /2 which is perfectly valid code in C90 evaluates to 1
while 2 in later version. When releasing later versions you are always
breaking someones insane code. It's a matter of compromises between breaking
0.00000000001% of the codebase and progress. The number of zeroes in that
percentage is of course debatable, see
[http://www.cl.cam.ac.uk/~pes20/cerberus/notes50-survey-
discu...](http://www.cl.cam.ac.uk/~pes20/cerberus/notes50-survey-
discussion.html) where a number of "Do you know of real code that relies on
it?" are answered by ~20% of yes and ~20% of no, that would be crazy. So it is
entirely possible the standards committee believes a construct is not used,
that'd be crazy but it actually is used.

~~~
ben0x539
no version of C++ ever added new comment syntax that a previous version of C++
didnt have, tho

~~~
Someone
Nitpick: as far as I can tell that's _almost_ correct.

[http://www.softwarepreservation.org/projects/c_plus_plus/ind...](http://www.softwarepreservation.org/projects/c_plus_plus/index.html#release_e)
leads me to
[http://www.softwarepreservation.org/projects/c_plus_plus/cfr...](http://www.softwarepreservation.org/projects/c_plus_plus/cfront/release_e/doc/ReferenceManual.pdf),
which shows that the first external C++ release didn't have // comments.

The first commercial release had, though
([http://www.softwarepreservation.org/projects/c_plus_plus/cfr...](http://www.softwarepreservation.org/projects/c_plus_plus/cfront/release_1.0/doc/ReleaseNotes-
Lifeboat.pdf))

~~~
ben0x539
Darn. :P

I was only thinking of the standardized ones, but you're correct, of course!

------
gpderetta
Because of SFINAE for expressions added in C++11 (which gives the capability
to test at compile time whether an arbitrary expression is valid or not),
technically _any_ change to the language or standard library can change the
behaviour of a valid C++ program.

------
pveierland
One behavioral change in C++11 is the noexcept specifier; with user-defined
destructors defaulting to noexcept(true). If you have pre-C++11 code throwing
exceptions from within a destructor, e.g. to signal a violated postcondition
contract, the program will terminate when such an exception is thrown after
compiling the program as C++11.

Updating the code to function under C++11 requires adding a noexcept(false)
specification to throwing destructors.

------
bluejekyll
This is really cool. Though, I have to say, I was hoping that it was examples
of undefined behavior and how that changes between versions and compilers.

But still, pretty neat in terms of features.

------
omoikane
Summary of all tricks used can be found here: [http://uguu-
archive.appspot.com/fuuko/source/c_version.c](http://uguu-
archive.appspot.com/fuuko/source/c_version.c)

~~~
Kristine1975
And
[http://ioccc.org/2015/yang/spoiler.html](http://ioccc.org/2015/yang/spoiler.html)
contains a Javascript-based replay of the author writing the program. From an
empty editor window to non-obfuscated code to the ASCII art face.

