Why should I always enable compiler warnings?

后端 未结 20 1624
时光说笑
时光说笑 2020-11-22 00:28

I often hear that when compiling C and C++ programs I should \"always enable compiler warnings\". Why is this necessary? How do I do that?

Sometimes I also hear tha

相关标签:
20条回答
  • 2020-11-22 01:04

    There's only one problem with treating warnings as errors: When you're using code coming from other sources (e.g., micro$**t libraries, open source projects), they didn't do their job right, and compiling their code generates tons of warnings.

    I always write my code so it doesn't generate any warnings or errors, and clean it up until it compiles without generating any extraneous noise. The garbage I have to work with appalls me, and I'm astounded when I have to build a big project and watch a stream of warnings go by where the compilation should only be announcing which files it processed.

    I also document my code because I know the real lifetime cost of software comes mostly from maintenance, not from writing it initially, but that's a different story...

    0 讨论(0)
  • 2020-11-22 01:07

    The other answers are excellent and I don't want to repeat what they have said.

    One other aspect to "why enable warnings" that hasn't properly been touched on is that they help enormously with code maintenance. When you write a program of significant size, it becomes impossible to keep the whole thing in your head at once. You typically have a function or three that you're actively writing and thinking about, and perhaps a file or three on your screen that you can refer to, but the bulk of the program exists in the background somewhere and you have to trust that it keeps working.

    Having warnings on, and having them as energetic and in your face as possible, helps to alert you if something you change makes trouble for something that you can't see.

    Take for example, the clang warning -Wswitch-enum. That triggers a warning if you use a switch on an enum and miss out one of the possible enum values. It's something you might think would be an unlikely mistake to make: you probably at least looked at the list of enum values when you wrote the switch statement. You might even have an IDE that generated the switch options for you, leaving no room for human error.

    This warning really comes into its own when, six months later you add another possible entry to the enum. Again, if you're thinking about the code in question you'll probably be fine. But if this enum is used for multiple different purposes and it's for one of those that you need the extra option, it's very easy to forget to update a switch in a file you haven't touched for 6 months.

    You can think of warnings in the same way as you'd think of automated test cases: they help you make sure that the code is sensible and doing what you need when you first write it, but they help even more to make sure that it keeps doing what you need while you prod at it. The difference is that test cases work very narrowly to the requirements of your code and you have to write them, while warnings work broadly to sensible standards for almost all code, and they're very generously supplied by the boffins who make the compilers.

    0 讨论(0)
  • 2020-11-22 01:07

    I once worked for a large (Fortune 50) company that manufactured electronic testing equipment.

    The core product of my group was an MFC program that, over the years, came to generate literally hundreds of warnings. Which were ignored in almost all cases.

    This is a frigging nightmare when bugs occur.

    After that position, I was lucky enough to be hired as the first developer in a new startup.

    I encouraged a 'no warning' policy for all builds, with compiler warning levels set to be pretty noisy.

    Our practice was to use #pragma warning - push/disable/pop for code that the developer was sure was really fine, along with a log statement at the debug level, just in case.

    This practice worked well for us.

    0 讨论(0)
  • 2020-11-22 01:08

    Non-fixed warnings will, sooner or later, lead to errors in your code.


    Debugging a segmentation fault, for instance, requires the programmer to trace the root (cause) of the fault, which usually is located in a prior place in your code than the line that eventually caused the segmentation fault.

    It's very typical that the cause is a line for which the compiler had issued a warning that you ignored, and the line that caused the segmentation fault the line that eventually threw the error.

    Fixing the warning leads to fixing the problem.. A classic!

    A demonstration of the above.. Consider the following code:

    #include <stdio.h>
    
    int main(void) {
      char* str = "Hello world!";
      int idx;
    
      // Colossal amount of code here, irrelevant to 'idx'
    
      printf("%c\n", str[idx]);
    
      return 0;
    }
    

    which when compiled with "Wextra" flag passed to GCC, gives:

    main.c: In function 'main':
    main.c:9:21: warning: 'idx' is used uninitialized in this function [-Wuninitialized]
        9 |   printf("%c\n", str[idx]);
          |                     ^
    

    which I could ignore and execute the code anyway.. And then I would witness a "grand" segmentation fault, as my IP epicurus professor used to say:

    Segmentation fault

    In order to debug this in a real world scenario, one would start from the line that causes the segmentation fault and attempt to trace what is the root of the cause.. They would have to search for what has happened to i and str inside that colossal amount of code over there...

    Until, one day, they found theirselves in the situation where they discover that idx is used uninitialized, thus it has a garbage value, which results in indexing the string (way) beyond out of its bounds, which leads to a segmentation fault.

    If only they hadn't ignored the warning, they would have found the bug immediately!

    0 讨论(0)
  • 2020-11-22 01:10

    Not only does handling the warnings make better code, it makes you a better programmer. Warnings will tell you about things that may seem little to you today, but one day that bad habit will come back and bite your head off.

    Use the correct type, return that value, evaluate that return value. Take time and reflect "Is this really the correct type in this context?" "Do I need to return this?" And the biggie; "Is this code going to be portable for the next 10 years?"

    Get into the habit of writing warning-free code in the first place.

    0 讨论(0)
  • 2020-11-22 01:11

    C is, famously, a rather low-level language as HLLs go. C++, though it might seem to be a considerably higher-level language than C, still shares a number of its traits. And one of those traits is that the languages were designed by programmers, for programmers -- and, specifically, programmers who knew what they were doing.

    [For the rest of this answer I'm going to focus on C. Most of what I'll say also applies to C++, though perhaps not as strongly. Although as Bjarne Stroustrup has famously said, "C makes it easy to shoot yourself in the foot; C++ makes it harder, but when you do it blows your whole leg off."]

    If you know what you are doing -- really know what you are doing -- sometimes you may have to "break the rules". But most of the time, most of us will agree that well-intentioned rules keep us all out of trouble, and that wantonly breaking those rules all the time is a bad idea.

    But in C and C++, there are surprisingly large numbers of things you can do that are "bad ideas" but which aren't formally "against the rules". Sometimes they're a bad idea some of the time (but might be defensible other times); sometimes they're a bad idea virtually all of the time. But the tradition has always been not to warn about these things -- because, again, the assumption is that programmers know what they are doing, they wouldn't be doing these things without a good reason, they'd be annoyed by a bunch of unnecessary warnings.

    But of course not all programmers really know what they're doing. And, in particular, every C programmer (no matter how experienced) goes through a phase of being a beginning C programmer. And even experienced C programmers can get careless and make mistakes.

    Finally, experience has shown not only that programmers do make mistakes, but that these mistakes can have real, serious consequences. If you make a mistake, and the compiler doesn't warn you about it, and somehow the program doesn't immediately crash or do something obviously wrong because of it, the mistake can lurk there, hidden, sometimes for years, until it causes a really big problem.

    So it turns out that, most of the time, warnings are a good idea, after all. Even the experienced programmers have learned (actually, it's "especially the experienced programmers have learned") that, on balance, the warnings tend to do more good than harm. For every time you did something wrong deliberately and the warning was a nuisance, there are probably at least ten times you did something wrong by accident and the warning saved you from further trouble. And most warnings can be disabled or worked around for those few times when you really want to do the "wrong" thing.

    (A classic example of such a "mistake" is the test if(a = b). Most of the time, this is a mistake, so most compilers these days warn about it -- some even by default. But if you really wanted to both assign b to a and test the result, you can disable the warning by typing if((a = b)).)

    The second question is, why would you want to ask the compiler to treat warnings as errors? I'd say it's because of human nature, specifically, the all-too-easy reaction of saying "Oh, that's just a warning, that's not so important, I'll clean that up later." But if you're a procrastinator (and I don't know about you, but I'm a terrible procrastinator) it's easy to put off the necessarily cleanup for basically ever -- and if you get into the habit of ignoring warnings, it gets easier and easier to miss an important warning message that's sitting there, unnoticed, in the midst of all the ones you're ignoring.

    So asking the compiler to treat warnings as errors is a little trick you can play on yourself to get around this human foible.

    Personally, I'm not as insistent about treating warnings as errors. (In fact, if I'm honest, I can say that I virtually never enable that option in my "personal" programming.) But you can be sure I've got that option enabled at work, where our style guide (which I wrote) mandates its use. And I would say -- I suspect most professional programmers would say -- that any shop that doesn't treat warnings as errors in C is behaving irresponsibly, is not adhering to commonly-accepted industry best practices.

    0 讨论(0)
提交回复
热议问题