Thread: Compiler Warnings

  1. #1
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654

    Compiler Warnings

    I'm not to keen on removing these warnings, so I would appreciate some help in sorting them out:

    UNSOLVED WARNINGS:
    ---START---
    Code:
    pBuffer = (T*)THROW_ERROR;
    Generates warning C4312: 'type cast' : conversion from 'const int' to 'int *' of greater size.
    Basically, it's a cast of INT to INT*, as you can see. This is simply because pBuffer wants a pointer (because it's a buffer!), but I'm throwing a value at it (on purpose of course).
    ---END---

    ---START---
    Code:
    PROCESS_STATUS( UpdateStatus(NULL, (pp<::CError>)pError) );
    Generates the warning C4239: nonstandard extension used : 'argument' : conversion from 'CMemoryManager<T>' to 'CMemoryManager<T> &'
    PROCESS_STATUS macro:
    Code:
    #define PROCESS_STATUS(exp) TempStatus = exp; \
    	switch(TempStatus) \
    	{ \
    		case STATUS_BAD: goto Next; \
    		case STATUS_CANCEL: bCancel = true; goto Next; \
    	}
    UpdateStatus declaration:
    Code:
    UpdateStatusEnum UpdateStatus(CFileMap* pFile, ppdef<::CError> pError = NULL);
    pp = class CMemoryManager<T>
    ppdef = class CMemoryManagerDefault<T>
    And declaration of pError:
    Code:
    pp<CKantanAnime::CError> pError;
    ---END---

    ---START---
    Code:
    return ReturnError(pFile, (CString)"Failed to write avisynth file because:\n\n" + GetError(pErrorLocal->dwError));
    Generates warning C4239: nonstandard extension used : 'argument' : conversion from 'ATL::CStringT<BaseType,StringTraits>' to 'CString &'
    Declaration of ReturnError:
    Code:
    CString& ReturnError(CFileMap* pFile, CString& strError);
    ---END---

    ---START---
    And the last warning is:
    warning C4244: '+=' : conversion from 'int' to 'BYTE', possible loss of data
    Example line:
    Code:
    posDst[j]+=(BYTE)(rand() / grainx2);
    Declarations:
    Code:
    BYTE	*iDst ,*posDst;
    long	sXSize,sYSize,bytes,j,i,k,h;
    int grainx2 = RAND_MAX/(max(1,2*granularity));
    And in case you've forgotten how rand() looks like:
    Code:
    _CRTIMP __checkReturn int    __cdecl rand(void);
    As you see, I already tried truncating the result to BYTE at the end, but it doesn't seem to help.
    I don't know if I have to truncate rand() and grainx2 to BYTE for it to work. But then again, wouldn't truncating them throw this warning too?
    ---END---

    ---START---
    Code:
    return MapHandle((HANDLE)0xFFFFFFFF);
    Generates warning C4312: 'type cast' : conversion from 'const int' to 'int *' of greater size.
    ---END---

    And a last question:
    The DX sdk headers seem to use a lot of the old, deprecated functions, like sprint (instead of sprint_f). Okay, so I just made that up, but it goes to show it uses old, depracted functions. I disabled warnings before including the header and then re-enabling them, but should this be? Are there no DX headers that includes the newer, safer versions?
    Using Visual Studio 2005. Appreciate answers. Thanks.

    ---SOLVED WARNINGS, BUT WAITING FOR AN EXPLANATION AS TO WHY---


    SOLVED WARNINGS:
    ---START---
    Code:
    void AddTool(CWnd * pWnd, DWORD dwIdString, DWORD dwIdIcon, CSize & szIcon = CSize(0, 0), LPCRECT lpRectBounds = NULL, DWORD dwIDTool = 0);
    This generates warning C4239: nonstandard extension used : 'default argument' : conversion from 'CSize' to 'CSize &'
    ---END---
    Last edited by Elysia; 10-25-2007 at 01:20 PM.

  2. #2
    Unregistered User Yarin's Avatar
    Join Date
    Jul 2007
    Posts
    2,158
    Have you tried the return MapHandle(HANDLE(0xFFFFFFFF));
    method rather than return MapHandle((HANDLE)0xFFFFFFFF);?

  3. #3
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Generates warning C4312: 'type cast' : conversion from 'const int' to 'int *' of greater size.
    Basically, it's a cast of INT to INT*, as you can see. This is simply because pBuffer wants a pointer (because it's a buffer!), but I'm throwing a value at it (on purpose of course).
    So, THROW_ERROR is a const int, and pBuffer is a buffer. How are they related?

    Generates warning C4312: 'type cast' : conversion from 'const int' to 'int *' of greater size.
    Change the return type of the function? Of course, whether that is a good or bad idea depends on the context.

    This generates warning C4239: nonstandard extension used : 'default argument' : conversion from 'CSize' to 'CSize &'
    Change:
    Code:
    CSize & szIcon = CSize(0, 0)
    to:
    Code:
    const CSize & szIcon = CSize(0, 0)
    A CSize& parameter should refer to an object outside of the function. However, by having a default argument, it may refer to an object local to the function instead. This is not a problem if a const reference is used instead.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  4. #4
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Quote Originally Posted by laserlight View Post
    So, THROW_ERROR is a const int, and pBuffer is a buffer. How are they related?
    They are related in the grand design. It's Registry code. The caller provides a buffer of type CBuffer. The caller can also provide a buffer to return if the value is not found. OR the caller can specify that an error should be thrown (or returned) instead of returning the return buffer.
    To return an error, the caller passes the constant int THROW_ERROR to the buffer and the function checks if the buffer pointer is == THROW_ERROR.
    In any case, I want to be able to assign THROW_ERROR as a (UINT*).

    Quote Originally Posted by Yarin View Post
    Have you tried the return MapHandle(HANDLE(0xFFFFFFFF));
    method rather than return MapHandle((HANDLE)0xFFFFFFFF);?
    Change the return type of the function? Of course, whether that is a good or bad idea depends on the context.
    Code:
    return MapHandle( HANDLE(0xFFFFFFFF) );
    Generates the same warning.
    However, I did notice that I can create a temp variable and initialize it to the value and pass it without generating a warning.

    Code:
    HANDLE hTemp = 0xFFFFFFFF;
    return MapHandle(hTemp);
    This code does not generate the warning for some reason.

    Change:
    Code:
    CSize & szIcon = CSize(0, 0)
    to:
    Code:
    const CSize & szIcon = CSize(0, 0)
    A CSize& parameter should refer to an object outside of the function. However, by having a default argument, it may refer to an object local to the function instead. This is not a problem if a const reference is used instead.
    I'm not truly sure I understand why this behaviour. A const reference works, but a non-const does not. Why is this?

    Updated main post to show solved/unsolved warnings.
    Last edited by Elysia; 10-25-2007 at 11:40 AM.

  5. #5
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    They are related in the grand design. It's Registry code. The caller provides a buffer of type CBuffer. The caller can also provide a buffer to return if the value is not found. OR the caller can specify that an error should be thrown (or returned) instead of returning the return buffer.
    To return an error, the caller passes the constant int THROW_ERROR to the buffer and the function checks if the buffer pointer is == THROW_ERROR.
    In any case, I want to be able to assign THROW_ERROR as a (UINT*).
    hmm... one possible option is to return 0 (or NULL, they are the same) as the error code. It is not safe to cast some arbitrary value to a pointer type, but 0 can be safely assigned to objects of any pointer type. Basically, the contract here would be that if the buffer is a null pointer, it is time to throw an error.

    I'm not truly sure I understand why this behaviour. A const reference works, but a non-const does not. Why is this?
    A temporary (the default argument, in this case) is an rvalue. One cannot assign an rvalue to a reference because one might attempt to modify the rvalue using the reference. One can assign an rvalue to a const reference because there is the guarantee not to change the value.

    If I remember correctly, the next version of the C++ standard will allow for rvalue references, but it will be with the introduction of new syntax.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  6. #6
    Registered User
    Join Date
    Apr 2006
    Posts
    2,149
    Quote Originally Posted by Elysia View Post
    I'm not truly sure I understand why this behaviour. A const reference works, but a non-const does not. Why is this?

    Updated main post to show solved/unsolved warnings.
    Temporary variables, including default arguments, are always const. A const value can only be referenced with a const reference.
    It is too clear and so it is hard to see.
    A dunce once searched for fire with a lighted lantern.
    Had he known what fire was,
    He could have cooked his rice much sooner.

  7. #7
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Quote Originally Posted by laserlight View Post
    hmm... one possible option is to return 0 (or NULL, they are the same) as the error code. It is not safe to cast some arbitrary value to a pointer type, but 0 can be safely assigned to objects of any pointer type. Basically, the contract here would be that if the buffer is a null pointer, it is time to throw an error.
    But that's not the same. If the buffer is NULL, then it attempt to create a buffer for you. It's all about convenience. You can query for a value without specifying a buffer and one will be created and returned instead.
    That's why you should specify THROW_ERROR (and store it in the buffer) if you want it to return or throw an error when the value you're looking for can't be found.

    A temporary (the default argument, in this case) is an rvalue. One cannot assign an rvalue to a reference because one might attempt to modify the rvalue using the reference. One can assign an rvalue to a const reference because there is the guarantee not to change the value.

    If I remember correctly, the next version of the C++ standard will allow for rvalue references, but it will be with the introduction of new syntax.
    I see. That makes sense. But what does not make sense is why you wouldn't be allowed to change a rvalue here, since the temporary object's lifetime should be as long as the function's lifetime (otherwise a const reference wouldn't work either).

  8. #8
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    But that's not the same. If the buffer is NULL, then it attempt to create a buffer for you. It's all about convenience. You can query for a value without specifying a buffer and one will be created and returned instead.
    That's why you should specify THROW_ERROR (and store it in the buffer) if you want it to return or throw an error when the value you're looking for can't be found.
    I see. If you really want such convenience, why not overload the function instead? One version takes a buffer and fills it if it can, setting the pointer to 0 otherwise. The other version returns the buffer, or a null pointer if the value cannot be found.

    But what does not make sense is why you wouldn't be allowed to change a rvalue here, since the temporary object's lifetime should be as long as the function's lifetime (otherwise a const reference wouldn't work either).
    That sounds like an argument for rvalue references. At the moment, I think it is mainly a matter of ideals: conceptually, an rvalue cannot be changed, even if "changing" it may not be harmful.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  9. #9
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    I could probably think of a different design, but... Does this mean that it's pretty much impossible to convert a value (like UINT, INT) to a pointer type? I know it will probably not yield a valid pointer, but that is irrelevant.

  10. #10
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Does this mean that it's pretty much impossible to convert a value (like UINT, INT) to a pointer type? I know it will probably not yield a valid pointer, but that is irrelevant.
    It is possible, of course. You "only" get a warning message after all. I have not encountered that warning myself, but I am guessing that this might be a 64-bit system thing: pointers are now 8 bytes, but int remains at 4 bytes, so the compiler complains of a mismatch.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  11. #11
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    This is 32-bit, x86. The strange thing is that if you do a sizeof(int), it will say 4. If you do a sizeof(int*), it will say 4.
    Even though it's a warning, clean builds (w/o warnings) are prefered, plus I chose to treat warnings like errors.

    EDIT:
    Changing
    Code:
    PROCESS_STATUS( UpdateStatus(NULL, (pp<::CError>)pError) );
    to
    Code:
    PROCESS_STATUS( UpdateStatus(NULL, (pp<::CError>&)pError) );
    Makes it compile fine without warnings. Anyone know why?

    EDIT2: The workaround for the casting of 0xFFFFFFFF to HANDLE didn't work apparently, even though I thought it did.
    I moved it back into unsolved.
    Last edited by Elysia; 10-25-2007 at 01:20 PM.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. how to call a compiler?
    By castlelight in forum C Programming
    Replies: 3
    Last Post: 11-22-2005, 11:28 AM
  2. Compiler "Warnings"
    By Jeremy G in forum A Brief History of Cprogramming.com
    Replies: 24
    Last Post: 04-24-2005, 01:09 PM
  3. Help With finding a compiler
    By macman in forum A Brief History of Cprogramming.com
    Replies: 4
    Last Post: 04-15-2005, 08:15 AM
  4. Compiler questions
    By DvdHeijden in forum C++ Programming
    Replies: 6
    Last Post: 01-17-2005, 03:00 PM
  5. Have you ever written a compiler?
    By ammar in forum A Brief History of Cprogramming.com
    Replies: 21
    Last Post: 12-27-2004, 07:10 AM