Thread: -Werror=conversion. Is this useful / necessary?

  1. #1
    Registered User
    Join Date
    May 2016
    Posts
    104

    -Werror=conversion. Is this useful / necessary?

    Code:
    extern unsigned long int get_absolutevalue(const long int number)
    {
        if(number < 0)   
            return (~number + 1);
        return (number)
    }
    Code:
        const unsigned int length = strlen(line);
    Code:
    error: conversion to ‘long unsigned int’ from ‘long int’ may change the sign of the result [-Werror=sign-conversion]
    error: conversion to ‘unsigned int’ from ‘size_t {aka long unsigned int}’ may alter its value [-Werror=conversion]
    I have similar idiotic complaints all over my code.
    I usually declare every variable that can't be negative, as unsigned, so there's plenty of errors like these everywhere.I started explicitly casting one by one to shut up the compiler when I wondered if this was really necessary.

    Since I'd like to be a good programmer some day and write good, standard compliant and error free code, I have to ask if there's any value in doing all this unnecessary casting or if I should get rid of the stupid flag?

    Thank you.

  2. #2
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,412
    It is not necesary for get_absolutevalue because you are explicitly checking for the situation where the conversion from signed to unsigned could result in an unexpected value. On the other hand, it seems easy enough to write and read:
    Code:
    unsigned long get_absolutevalue(const long number)
    {
        return (unsigned long)((number < 0) ? (~number + 1) : number);
    }
    There's no need to declare the function extern since it already has external linkage by default.

    For string length, it would be better for you to just use a const size_t instead of a const unsigned int, although a const unsigned long would have done the trick too.

    Incidentally, is there a reason why you prefer (~number + 1) over -number? The latter seems more straightforward; your implementation technically requires two's complement, and although two's complement is almost certainly going to be the case (I think even the most obscure systems these days use it), in theory one's complement or sign & magnitude could be the signed integer representation system.
    Last edited by laserlight; 10-17-2018 at 08:58 PM.
    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

  3. #3
    Registered User
    Join Date
    May 2016
    Posts
    104
    I was looking for more of a “yes the flag is useful because of x, y, z” or “don’t bother with it” type of answer. From your reply, I gather you think it’s more of a “it depends situation” which seems to imply it might be useful after all. In my case, I fail to see the advantage, when all I’m doing is explicitly casting types all over the place. Perhaps I should be more careful in the future and use similar types as you recommend.


    There's no need to declare the function extern since it already has external linkage by default
    I know, I do it for consistency.
    Incidentally, is there a reason why you prefer
    One of my first projects required doing an absurd amount of recursive calculations within a certain time frame, and I wasn’t allowed to use any compiler optimizations. That particular sequence disassembled into faster instructions -according to the Intel instruction manuals – than the alternative, so I went with it. Interestingly, on my current machine, both translate into the same “neg” instruction and when optimizing, that is replaced with a right shift, xor and sub.

  4. #4
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    I guess the question becomes whether you already knew these were different types before you got the error messages; if not, then you've learned that there's something to worry about and you can decide, in your situation, whether you need to adjust things. (For instance, if you didn't know that strlen could return something bigger than an (unsigned) int, that could have been a problem -- unless you know that the inputs to this program won't ever be that long.) (EDIT TO ADD: And even if you did know that your result will always fit in an int, there's probably still no reason to use the right type (size_t) instead, unless you are really crunched for memory.)
    Last edited by tabstop; 10-17-2018 at 10:18 PM.

  5. #5
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,412
    Quote Originally Posted by Dren
    I was looking for more of a “yes the flag is useful because of x, y, z” or “don’t bother with it” type of answer. From your reply, I gather you think it’s more of a “it depends situation” which seems to imply it might be useful after all. In my case, I fail to see the advantage, when all I’m doing is explicitly casting types all over the place.
    Yes, it is useful: it highlights places in your code where you may have neglected to take care concerning conversion from signed to unsigned or vice versa, or where you may have neglected to take care concerning conversion from a type with a larger range to a type with a smaller range.

    If you actually did take the requisite care, then of course it is not useful, but then if you have an extremely comprehensive battery of unit and integration tests with pretty much full coverage that you always run and ensure all tests pass, then pretty much all warnings are not useful beyond helping to fix a problem detected by a failed test. (If I remember correctly, this was the position taken by the author of SQLite as to why he wouldn't fix "spurious warnings" in the SQLite codebase.)

    In your case, if you do indeed have such a confidence-inducing battery of tests, then go ahead and ignore them: those warnings are truly spurious. If not, it might be a good idea to look over them: they could indicate that you might want to change the types to avoid the conversions (i.e., only perform the conversions at specific "boundaries" rather than all over the place), or perhaps you really do want the conversions and know that they are safe (perhaps the casts, while ugly, might document that).
    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
    May 2016
    Posts
    104
    I concede it is better to be notified of a possible mistake than being unaware and blindly making it. I expect things to be more manageable if I use during development as I can adjust my code as I go.

    This time things will stay as they are. I made an honest effort to fix the warnings but raged quit after finding this little treasure:
    Code:
    unsigned int size =  0;
     ...
    size += sizeof(int);
    Code:
    error: conversion to ‘unsigned int’ from ‘long unsigned int’ may alter its value [-Werror=conversion]

    Anyway, thank you kindly for your answers.
    :thumbsup:

  7. #7
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,412
    That looks like a compiler bug, or maybe being a little overzealous as it might be possible for size_t to be equivalent to unsigned short (with sizeof(unsigned short) < sizeof(unsigned int)), so the error message was generated based on that kind of supposition, but looks wrong when size_t is equivalent to unsigned long as there can be no change of value converting from unsigned int to unsigned long. Still, the type of the result of sizeof is indeed size_t so that's typically the best option to store that result.
    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

  8. #8
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,656
    There's also reading the man page.
    Using the GNU Compiler Collection (GCC): Warning Options

    -Wconversion

    Warn for implicit conversions that may alter a value. This includes conversions between real and integer, like abs (x) when x is double; conversions between signed and unsigned, like unsigned ui = -1; and conversions to smaller types, like sqrtf (M_PI). Do not warn for explicit casts like abs ((int) x) and ui = (unsigned) -1, or if the value is not changed by the conversion like in abs (2.0). Warnings about conversions between signed and unsigned integers can be disabled by using -Wno-sign-conversion.

    For C++, also warn for confusing overload resolution for user-defined conversions; and conversions that never use a type conversion operator: conversions to void, the same type, a base class or a reference to them. Warnings about conversions between signed and unsigned integers are disabled by default in C++ unless -Wsign-conversion is explicitly enabled.
    > I usually declare every variable that can't be negative, as unsigned, so there's plenty of errors like these everywhere.
    So use the -Wno-sign-conversion to just exclude the signed-ness warnings.

    > I started explicitly casting one by one to shut up the compiler when I wondered if this was really necessary.
    Over zealous casting will eventually remove the possibility of the compiler telling you anything useful about the code.

    > unsigned int size = 0;
    > ...
    > size += sizeof(int);
    So make size be a size_t rather than an unsigned int, and the problem goes away.

    Consider your types more carefully, and don't just lazily say "everything's an unsigned int" if it can't be negative.

    The warning exists in part to highlight possible portability issues. True, the magnitude of any object sizes you're likely to accumulate through using sizeof() is unlikely to result in overflowing an unsigned int, but on machines where sizeof() is an unsigned long, there exists the possibility of accumulating object sizes that would cause an overflow.

    CVE security vulnerability database. Security vulnerabilities, exploits, references and more
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. bcc conversion
    By sjhawar in forum C Programming
    Replies: 1
    Last Post: 06-12-2011, 01:50 PM
  2. How would you do this conversion?
    By redruby147 in forum C Programming
    Replies: 11
    Last Post: 04-04-2009, 02:38 PM
  3. conversion
    By ashok449 in forum C Programming
    Replies: 2
    Last Post: 03-04-2008, 03:35 AM
  4. Need help in Conversion
    By saravanan_ts in forum Windows Programming
    Replies: 0
    Last Post: 10-16-2003, 05:16 AM
  5. Conversion
    By Unregistered in forum C++ Programming
    Replies: 3
    Last Post: 02-27-2002, 04:31 PM

Tags for this Thread