为什么gcc警告我这条线是"误导性地缩进,就好像它被"一个if?

Dro*_*onz 3 c++ gcc-warning

警告是:

/home/dronz/OF/apps/myApps/HexMap/src/HexMap.cpp:48:5: warning: this ‘if’ clause 
does not guard... [-Wmisleading-indentation]
     if (toHexSize < 1)
     ^~
/home/dronz/OF/apps/myApps/HexMap/src/HexMap.cpp:51:2: note: ...this statement, 
but the latter is misleadingly indented as if it were guarded by the ‘if’
  MapTileSizeAtZoom = toHexSize;
  ^~~~~~~~~~~~~~~~~
Run Code Online (Sandbox Code Playgroud)

代码是这样的:

if (toHexSize < 1)
    toHexSize = 1;

MapTileSizeAtZoom = toHexSize;
Run Code Online (Sandbox Code Playgroud)

如果MapTileSizeAtZoom ...线条缩进更多,我可以看到它有误导性,但它与'if'处于相同的缩进水平,所以这对我来说似乎是正确的.

我想也许有额外的空间和/或标签浮动,但我在文本后删除了任何不必要的空白字符,这没有任何区别.

我想也许它被空白线弄糊涂了,但把它取出并没有停止警告.

此外,在相同的.cpp文件之前是这段代码,它没有警告:

if (toHexSize < 1)
    toHexSize = 1;

HexInfo centerOnHex;
if (SelectedHex.type != -1)
Run Code Online (Sandbox Code Playgroud)

所以我想知道为什么它会警告一个(根本),以及它为什么不警告另一个,这是否是一个gcc bug,以及如何避免它?

...

编辑:@NeilButterworth让我发布"所有代码".(似乎没有相关性,但他有2.5万的声誉,所以我在下面添加了它.)

#include "HexMap.h"
#include <algorithm>
#include <cmath>

//--------------------------------------------------------------
HexMap::HexMap()
{}

//--------------------------------------------------------------
int HexMap::SetZoom(int toHexSize)
{
    if (toHexSize < 1)
        toHexSize = 1;

    HexInfo centerOnHex;
    if (SelectedHex.type != -1)
    {
        // Center map on the selected hex.
        centerOnHex = SelectedHex;
    }
    else
    {
        // Center map on current center of viewpoint.
        centerOnHex = GetHex(
            MapFrame.x + MapFrame.getWidth() / 2,
            MapFrame.y + MapFrame.getHeight() / 2 );
        if ((centerOnHex.x > WORLDMAPWIDTH) || (centerOnHex.x < 0))
            centerOnHex.x = WORLDMAPWIDTH / 2;
        if ((centerOnHex.y > WORLDMAPHEIGHT) || (centerOnHex.y < 0))
            centerOnHex.y = WORLDMAPHEIGHT / 2;
    }

    setHexDisplaySize(toHexSize);

    // Center map:
    HexOriginX = MapFrame.x + MapTileWidth  * 0.25f;
    HexOriginY = MapFrame.y + MapTileHeight * 0.5f;
    ViewPosOnWorld.set(
        centerOnHex.x - (MapFrame.getWidth() / 2) / MapTileWidth, 
        centerOnHex.y - (MapFrame.getHeight() / 2) / MapTileHeight);

    return 0;
}

//--------------------------------------------------------------
void HexMap::setHexDisplaySize(int toHexSize)
{
    if (toHexSize < 1)
        toHexSize = 1;

    MapTileSizeAtZoom = toHexSize;
    MapTileWidth = MapTileSizeAtZoom * 1.5f; // hex x-spacing is 1.5 * r
    MapTileHeight = MapTileSizeAtZoom * 1.73205f; // hex height = sqrt(3*r)

    // Size images & hexmask:
    MaskWidth = MapTileHeight * 1.154700538;  // 1/(sqrt(3)/2)
}
Run Code Online (Sandbox Code Playgroud)

Dro*_*onz 15

在这里输入所有这个问题之后,我自然发现有用于缩进条件行49的空格,但是使用制表符来缩进第51行.

所以我想我也可以回答我自己的问题而不是删除它,以防其他人对此感到困惑.

有意义的是编译器无法比较空格和制表符,所以它不是一个错误.这是与空格缩进一致的另一个原因(例如,通过避免在源代码中使用任何选项卡).

  • 选项 *[-Wmisleading-indentation](https://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html#index-Wmisleading-indentation)* (3认同)
  • 使用诸如clang-format之类的格式化程序是避免将来出现此类问题并在存储库中实现代码样式一致性的一种好方法。 (2认同)
  • 或者通过始终在 if 语句中使用大括号来完全避免该问题,除非整个 if 语句都在一行上。养成这个习惯以后,当您在 if 块中添加第二条语句而忘记添加大括号时,会省去您的痛苦。 (2认同)
  • 您还可以在大多数 IDE 上将制表符设置为转换为空格。我在大型机上最早的脚本之一是 rogstop,它将 COBOL 的缩进与句号的位置进行比较(没有大括号,它们太复杂了,所以块只是最后没有句号的代码行。是的 -有人发现了数十个错误,要么在最后一行缺少句号,要么在中间多了一个句号。 (2认同)
  • *“GCC 将制表符视为 8 个空格”*:[一些证据](https://gcc.gnu.org/gcc-6/porting_to.html):*“默认情况下,-Wmisleading-indentation 假定制表符是8 个空格宽。"* (2认同)
  • 更改它的选项(例如,更改为更合理的 4 个空格)是 [`-ftabstop`](https://gcc.gnu.org/onlinedocs/gcc/Preprocessor-Options.html#index-ftabstop)。 (2认同)