18
grep
2y

With the brand new Microsoft C++ compiler, what you see in the debugger, is not always what you get...

Comments
  • 6
    Cool, didn't even know __LINE__ exists
  • 1
    Yea you have undefined behavior by I.o.b. Advice: in C the compiler usually isn't wrong.
  • 0
    @LicensedCrime its just pointer arithmetics, the intent of &a[1][3] is to point to the address past the last element of the array, like std::vector end() method.
    The issue here is that dist1 is different at runtime than dist2 as seen in the console at the bottom right. This bug appears only with the constexpr stuff, no problem without that. (Also the debugger shows the right value dist1 = 6, not 3)
  • 1
    @ComradeBob Yeah, I'm pretty impressed!
  • 1
    It's not weird it's undefined. That is it may or may not work depending on external conditions. In this case it's undefined to take a pointer to an element past the end of the array, doesn't matter if it is 'just pointer maths'
  • 0
    @stevemk14ebr I disagree, please read http://wiki.c2.com//.... That part:
    "According to the C and C++ standards, pointer arithmetic is only valid within an array or just off the end of it - it is valid to point to "one past the end" of the array provided that such pointers are never dereferenced."
    Again this is used in the STL for std::vector::end(). Maybe you are working for Microsoft ? ;-)
  • 0
  • 0
    @runfrodorun get em!!!
  • 0
    Congratulations, you have found a bug in the Microsoft c++ compiler. I guess all things considered that ain’t too tough to do. The example works just fine in gcc.

    It’s hard to say exactly where the strange behavior is coming into play, but it’s possible your system chose to view the array as 64 bit words, or the math might simply be wrong.

    The reason you see different behavior if you place the 1 and 3 in a variable is likely because the compile time calculation is not being picked up because Microsoft has a crappy optimizer. Global .data declarations are initialized before main is called, so you could be causing the computation to run at runtime as opposed to at compile time as it likely would do when you do not do this.

    For those who asked yes __LINE__ __FILE__ __FUNCTION__ and __PRETTY_FUNCTION__ are useful preprocessor macros that you can use. They are string literals that will be written into Read only program memory at compile time. So no overhead.
  • 0
    FWIW you can ask for a[100 ][ 100 ] if you wish, as that just translates into a pointer that points to ( a + 400 * sizeof( int ) )
  • 0
    TBH I would stay away from all this new age c++ crap like ptrdiff_t. It’s way too pointless... and I don’t like encouraging pointless crap. Much better to just declare it as an int* (matching) or worst case a void*. That’s the original technique and I guess someone someday decided we need an 80th typedef for void* which we do not.
Add Comment