c++headercompile-timegcc-pedantic

C++ g++ -pedantic warning


I am studying Bjarne Stroustrup's book 'Programming Principles and Practice Using C++'. I downloaded his header file from here and used the following compiling command in VSCode on Windows:

g++ -Wall -Wextra -Wconversion -pedantic -std=c++17 -g -c main.c

The compiler threw up a bunch of errors:

std_lib_facilities.h: In member function 'char& String::operator[](unsigned int)':
std_lib_facilities.h:114:8: warning: comparison of unsigned expression < 0 is always false [-Wtype-limits]
   if (i<0||size()<=i) throw Range_error(i);
       ~^~
std_lib_facilities.h: In member function 'const char& String::operator[](unsigned int) const':
std_lib_facilities.h:120:8: warning: comparison of unsigned expression < 0 is always false [-Wtype-limits]
   if (i<0||size()<=i) throw Range_error(i);
       ~^~
std_lib_facilities.h: At global scope:
std_lib_facilities.h:222:2: warning: extra ';' [-Wpedantic]
 };

My questions are:

  1. Is it correct to remove the semi-colon on line 222? The code in question:
default_random_engine& get_rand()
{
    static default_random_engine ran;
    return ran;
};
  1. What is the possible fix for the unsigned expression < 0 is always false?
  2. What should I watch out for in the future going forward using g++ (mingw64)? If possible, what are some resources to learn how to use about the g++ compiler effectively?

The code to be compiled was just a simple hello world. Thanks


Solution

  • 1.

    That semicolon is redundant. It’s only mandatory after the closing brace } of a class, struct, enum or union definition.

    2.

    As the error message says, an unsigned type can never have a negative value, so testing if (i<0) is useless. The compiler warns because such a useless test is an indicator for a probable mistake somewhere in the code. How you fix it is hard to say. Either the comparison is redundant and can be removed; or i should not be an unsigned type and needs to be changed. In the end that’s a design choice.

    3.

    With your current warning settings you’re already using the safety net provided by the compiler extensively. That’s good. Now make it a habbit to check those warnings and fix them. Your goal should be a clean compilation with no warnings at all. Especially during heavy development you can’t always achieve that. But keep the times where you do have warnings as short as possible.

    The less brain power you need to use to avoid silly mistakes the more you have left for the logic you’re implementing. With a bit of practice it’s suprisingly quick to get to the “if it compiles it works” (most of the time) stage.

    In understanding GCC I wouldn’t go beyond the warnings settings at the moment. You don’t want to call g++ directly for anything else than hello world examples anyway. For more complex projects you need a build system that does all the orchestration and configuration for you. In the C++ world that means CMake. A good overview over current practices is Effective Modern CMake. Especially have a look at the videos in the Getting Started section.