Expected -22 WTFs



  • How to reproduce it? Simple...

    void *whatever;
    (*whatever)(0, 0);

    Created by accident when refactoring, rewriting, making big mess from ugly code...


  • Considered Harmful

    @viraptor said:

    void *whatever;
    (*whatever)(0, 0);

    Can you dereference a void pointer like that (especially an uninitialized one)?  This looks like the infamous "undefined behavior" I'm always hearing about.  Things like this make me glad I've moved on to managed code.  It precludes several broad classes of WTF.



  • This looks like the output of MS cl.exe, which version has this bug? Just tried with 14.0.50727.42, it shows the correct number of arguments (2).

     
    @joe.edwards@imaginuity.com said:

    Can you dereference a void pointer like that (especially an uninitialized one)?  This looks like the infamous "undefined behavior" I'm always hearing about.  Things like this make me glad I've moved on to managed code.  It precludes several broad classes of WTF.

    You can't, which is why the compiler throws an error, there's no undefined behavior here.



  • @Reweave said:

    This looks like the output of MS cl.exe, which version has this bug? Just tried with 14.0.50727.42, it shows the correct number of arguments (2).


    @joe.edwards@imaginuity.com said:

    Can you dereference a void pointer like that (especially an uninitialized one)?  This looks like the infamous "undefined behavior" I'm always hearing about.  Things like this make me glad I've moved on to managed code.  It precludes several broad classes of WTF.

    You can't, which is why the compiler throws an error, there's no undefined behavior here.

     

    You can't, but just to clarify, it has nothing to do with whether or not the pointer was initialized (a decent compiler may give a warning if you use an uninitialized pointer, but it's not illegal to do so).



  •  @??? said:

    Filed under: whythehellshouldwetagtextposts



  • " It precludes several broad classes of WTF."

     But, as compensation, provides copious WTFs in the area of performance.



  • @Morbii said:

    @Reweave said:

    @joe.edwards@imaginuity.com said:

    Can you dereference a void pointer like that (especially an uninitialized one)?  This looks like the infamous "undefined behavior" I'm always hearing about.

    You can't, which is why the compiler throws an error, there's no undefined behavior here.

    You can't, but just to clarify, it has nothing to do with whether or not the pointer was initialized (a decent compiler may give a warning if you use an uninitialized pointer, but it's not illegal to do so).

    Dereferencing a pointer-to-void has implicitly undefined behavior, because of the definition of the indirection operator.  ISO 9899-1999 6.5.3.2 #4, which defines the result of the * operator, only covers pointer-to-function and pointer-to-object types as operands.  "void *" is an incomplete pointer type, so it is neither, so the behavior is not defined.  Morbii is correct that initialization is irrelevant in this case; Reweave is incorrect about the lack of UB.

    However, undefined behavior only applies during execution, not during translation, so the odd diagnostic from the compiler can't be ascribed to UB.

    There is a constraint violation: the pointer in question is not a pointer to function type, so it can't be the operand of the function-call operator (6.5.2.2 #1).  A conforming implementation must emit at least one diagnostic when translating a source file that contains at least one constraint violation.  Since the standard has no quality requirements for diagnostics, however, the one shown by the OP is perfectly conforming.  "Your program contains 0 errors" would be conforming, too, regardless of how many errors were found.

    (Strangely, applying the * operator to a void* operand is not a constraint violation, though applying the "[]" array-subscripting operator is.  I think that's because the "&" address-of operator and the * operator are defined to cancel one another out, regardless of the validity of the operand, as long as the operand is a pointer type.  So "void *foo = 0; &*&*foo;" is valid, though it has no side effects.  & cancels out [], too, but the result still has implicit pointer arithmetic, which is not defined for void pointers.)

    I'm afraid Morbii's wrong about whether it's "illegal" to dereference an uninitialized pointer, if by "illegal" we mean "invokes undefined behavior".  Any use of the value of an uninitialized variable invokes UB, and any use of the indirection operator with an operand that has an invalid value invokes UB.
     



  • @MichaelWojcik said:

    @Reweave said:

    @joe.edwards@imaginuity.com said:

    Can you dereference a void pointer like that (especially an uninitialized one)?  This looks like the infamous "undefined behavior" I'm always hearing about.

    You can't, which is why the compiler throws an error, there's no undefined behavior here.

    Dereferencing a pointer-to-void has implicitly undefined behavior, because of the definition of the indirection operator.  ISO 9899-1999 6.5.3.2 #4, which defines the result of the * operator, only covers pointer-to-function and pointer-to-object types as operands.  "void *" is an incomplete pointer type, so it is neither, so the behavior is not defined.

    Shows what I know. I thought it was not valid, thanks for correcting.


Log in to reply