【问题标题】:C++ g++ -pedantic warningC++ g++ - 迂腐警告
【发布时间】:2020-05-03 06:54:10
【问题描述】:

我正在学习 Bjarne Stroustrup 的书“使用 C++ 进行编程原理和实践”。我从here下载了他的头文件,并在Windows的VSCode中使用了如下编译命令:

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

编译器抛出一堆错误:

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]
 };

我的问题是:

  1. 删除第 222 行的分号是否正确? 有问题的代码:
default_random_engine& get_rand()
{
    static default_random_engine ran;
    return ran;
};
  1. unsigned expression &lt; 0 is always false 的可能修复方法是什么?
  2. 今后使用 g++ (mingw64) 应该注意什么?如果可能,有哪些资源可以学习如何有效使用 g++ 编译器?

要编译的代码只是一个简单的 hello world。 谢谢

【问题讨论】:

  • 第二季度。 unsigned int 始终为正数或零,因此“i
  • 我想了很多,但我仍然不确定。这是否意味着只要 i 的输入为负数,编译器就会自动抛出错误标志?
  • 不,它不能是负面的。如果您编写类似“unsigned int i=-1”的代码,则 i 的值将是 unsigned int 的最大值。
  • @karln-create 编译器很可能会完全删除代码,因为它不可能发生。
  • i &lt; 0 是 Stroustrup 代码中的一个明显错误,而不是编译器问题。显而易见的解决方法是不检查无符号类型是否为负数……您可能想检查该书的版本是否有一些已发布的勘误表。

标签: c++ header compile-time gcc-pedantic


【解决方案1】:

1.

那个分号是多余的。仅在类、结构、枚举或联合定义的右大括号 } 之后是强制性的。

2.

正如错误消息所说,unsigned 类型永远不能有负值,因此测试 if (i&lt;0) 是没有用的。编译器会发出警告,因为这种无用的测试表明代码中某处可能存在错误。你如何解决它很难说。要么比较是多余的,可以去掉;或i 不应是无符号类型,需要更改。归根结底,这是一种设计选择。

3.

通过您当前的警告设置,您已经在广泛使用编译器提供的安全网。那挺好的。现在养成检查这些警告并修复它们的习惯。您的目标应该是完全没有警告的干净编译。尤其是在繁重的开发过程中,你不能总是做到这一点。但请尽量缩短您确实发出警告的时间。

为了避免愚蠢的错误,你需要使用的脑力越少,你为正在实施的逻辑留下的余地就越多。通过一些练习,可以非常快地进入“如果它编译它就可以工作”(大多数情况下)阶段。

在理解 GCC 时,我目前不会超出警告设置。无论如何,除了 hello world 示例之外,您不想直接调用 g++。对于更复杂的项目,您需要一个为您完成所有编排和配置的构建系统。在 C++ 世界中,这意味着 CMake。 Effective Modern CMake 是对当前实践的一个很好的概述。尤其是观看入门部分中的视频。

【讨论】:

  • 另外,根据你的回答,我认为问题 1 中的构造应该是一个函数,对吗?
  • 我不确定我是否完全理解您的问题。是的,问题 1 构造是一个以右大括号结尾的函数定义。这很好。然后是一个杂散的分号。这也很好,但什么也没做。我猜编译器警告是存在的,因为有时 C++ 需要在块 {} 之后使用分号,而有时则不需要。有时,即使是语言的创造者也会对此感到困惑。 ;)
  • 谢谢,这就是我想要的。由于为函数声明的类型,我不确定。我还是个新手,还有很多我可能还不知道的构造类型。然后还有不同标准的合规性问题。我也学会了在隐含答案时不要相信我的解释。我宁愿被称为愚蠢但得到一个直接的答案,而不是在阳光明媚的日子里坚持下去并破坏我的代码。 :P
猜你喜欢
  • 2012-04-30
  • 1970-01-01
  • 1970-01-01
  • 2013-01-22
  • 2020-01-25
  • 1970-01-01
  • 2014-04-25
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多