Using variables before they exist...



  • Found a whole bunch of WTFs in a project from a previous lead programmer, but this one (C++) stumped me for a while:

     CSound* sound = sound->SetVolume(v);

     
    This actually worked, the compiler was fine with it and produced no errors. Turns out SetVolume was a class method, not an instance method, and it actually created a new CSound object. (I don't recall if SetVolume was the exact name, but it was nothing even close to suggesting its true behavior.)  The fact that sound was a CSound* was apparently enough to get the type and allow a class method call.

     Now, I don't know the C++ Standard quite that well to know if this is valid or not. Even if it was, it's most definitely a WTF for me...



     



  • Depending on programming languages, "this" or "self" is nothing else than an implicit parameter to functions that are called, then, methods. As a static method does not use "this", no error occurs.

    As for this case in particular, if I remember well,  knowing your sound is a CSound pointer, the compiler binds this call to the static method, and that's enough. The funny part is that we tend to read assignation statements from right to left but here the declaration prevails.

     I think it wouldn't have worked on a polymorphic pointer, since pointed vtable would have been some random memory place. But I'm not sure, I'm no longer into C++ for quite a while.
     



  • @mattmoss said:

     CSound* sound = sound->SetVolume(v);

    Actually, the correct way to do that in C++ is like this:

    CSound* sound = CSound->SetVolume(v);

    If it is in fact a class method, then that will avoid problems.



  • ITYM CSound* sound = CSound::SetVolume(v);

    The -> operator requires a pointer on the left side (or an object with operator-> defined).  The scope operator :: can be applied to any symbol to qualify the symbol following it.
     


  • Considered Harmful

    @el cubano said:

    @mattmoss said:

     CSound* sound = sound->SetVolume(v);

    Actually, the correct way to do that in C++ is like this:

    CSound* sound = CSound->SetVolume(v);

    If it is in fact a class method, then that will avoid problems.

    It's been a while since I used C++, but I thought the correct syntax for static methods was CSound::SetVolume( v );



  • Quite right. I've been away from my C++ a little too long.



  • @mattmoss said:

    Found a whole bunch of WTFs in a project from a previous lead programmer, but this one (C++) stumped me for a while:

     CSound* sound = sound->SetVolume(v);

    ...

     Now, I don't know the C++ Standard quite that well to know if this is valid or not. Even if it was, it's most definitely a WTF for me...


    It is definitely not valid, even though the code is invoking a static method. This falls into the realm of what the C++ standard defines as "undefined behavior". Thus, the previous code might do what the author expected, might crash, or it could launch a nuclear missle strike - one can't tell. 

    Of course, pretty much any C++ implementation will just call the static method without dereferencing 'sound', and the code will work as expected. But it doesn't have to.

    -matt





  • @elazro said:


    It is definitely not valid, even though the code is invoking a static method. This falls into the realm of what the C++ standard defines as "undefined behavior". Thus, the previous code might do what the author expected, might crash, or it could launch a nuclear missle strike - one can't tell.

     

    Yeah, that's basically what I expected.  This was an old, custom version of gcc, if I recall correctly, used to compile for the original PlayStation.

     



  • @el cubano said:

    @mattmoss said:

     CSound* sound = sound->SetVolume(v);

    Actually, the correct way to do that in C++ is like this:

    CSound* sound = CSound->SetVolume(v);

    If it is in fact a class method, then that will avoid problems.

     

    Except for the problem that, as the OP pointed out:

    "I don't recall if SetVolume was the exact name, but it was nothing even close to suggesting its true behavior."




  • Chicken *mychicken = mychicken->hatchegg();


Log in to reply