使用此代码:
#include <iostream>
int main(int argc, char *argv[])
{
return 0;
}
/** run2: A macro to call a function. */
#define run2( function, ctype, dim ) \
if ( operation == #function ) \
{ \
if ( componentType == #ctype && Dimension == dim ) \
{ \
typedef itk::Image< ctype, dim > ImageType; \
function< ImageType >( inputFileName, outputFileName, radius, algorithm, useCompression ); \
supported = true; \
} \
}
我收到警告:文件末尾的反斜杠换行符
知道如何让它消失吗?
大卫
答案 0 :(得分:14)
问题是代码末尾没有换行符。 C ++标准§2.1/ 2说:
&lt; ...&gt;如果源文件不是 空不会以换行结束 字符,或以新行结尾 字符紧跟在前面 反斜杠字符,行为是 未定义。
答案 1 :(得分:2)
让您的文件(翻译单元)不以换行符结尾undefined behavior,这意味着您的程序行为变得不可预测。虽然在C ++ 11中这种情况发生了变化,但预处理器的行为就好像有一条换行符一样。
有趣的是,为什么这是一个问题,我们可以从早期C ++ 11标准草案中通过include
包含文件从16.2
来源获得以下效果文件包含,其中说:
表单
的预处理指令# include " q-char-sequence" new-line
导致该指令的全部内容被替换 源文件由“...之间的特定序列标识” 分隔符。
因此,如果包含的文件没有以换行符结尾,我们应该如何处理包含文件的组合最后一行以及源代码中的后续行?有几个明显的问题,例如,如果包含文件中的最后一行结束:
它将改变使用include的源文件的解释方式,这不是一个理想的功能。这也包含在The New C Standard中( C也有相同的规则),它说:
如果包含文件的最后一行有什么行为应该是什么 不是以新线结束?字符应该在行的开头 跟着 #include指令被认为是任何前面的预处理令牌的一部分(从包含文件的最后一行)?要么 也许源文件应被视为在其末尾包含隐式换行符。 此要求通过呈现行为简化了这种情况 未定义
为了完整起见,预先C ++ 11标准草案部分2.1
翻译阶段说(强调我的前进):
[...]如果非空的源文件未以换行结束 字符,或以紧接在a之后的换行符结尾 反斜杠字符,行为未定义。
[...]一个非空的源文件,它不以a结尾 换行符,或者以换行符结束 在任何此类拼接之前使用反斜杠字符 地方,应该被处理,好像是一个额外的新行字符 附加到文件。
答案 2 :(得分:1)
以下代码在g ++ 4.3.4和g ++ 4.5.1下生成相同的警告:
int main() {}
#define X \
Y
我必须说我不明白为什么。但是你可以通过在文件末尾添加一个空行来消除警告。
顺便说一下,即使没有空的最后一行,这也会在没有警告的情况下进行编译:
int main() {}
#define X Y
所以它对我来说看起来像是一个预处理器错误。
编辑添加:好的,不是这样的错误。有关更深思熟虑的观点,请参阅我的其他答案。
答案 3 :(得分:0)
猜测一下,你所缺少的是最后一个结束后的新线。编译器警告这一点是合理的(C和C ++标准说它给出了未定义的行为),但是消息的文本误导了问题的根源。
答案 4 :(得分:0)
您文件中的最后一行可能不会以换行符终止吗?文件末尾的最后一行是必需的,但有些编辑只是因为讨厌的乐趣而不写它(IIRC visual studio)。
答案 5 :(得分:0)
正如Kirill V. Lyadvinsky指出的那样,目前的标准坚持在每个源文件末尾都有换行符。幸运的是,不符合输入的行为是未定义的,因此编译器可以自由地忽略这个愚蠢的规则。他们大多数都是。但是标准让预处理器可以自由地拒绝这种情况,而你似乎偶然发现了这种情况。当然,g ++并没有拒绝它出于什么?所以它必须是(不是错误,因为标准允许它,但是)意外的行为。
好消息是C ++ 11做对了:
2.2翻译阶段
一个非空的源文件 这不会以新的方式结束 字符,或以新行结尾 字符紧跟在前面 任何此类之前的反斜杠字符 拼接发生,应该是 处理好像是一个额外的新线 字符被附加到文件中。
所以你的代码将在不久的将来编译。