As far as I know \
in C just appends the next line as if there was not a line break.
据我所知,在C中只是附加下一行,好像没有换行符。
Consider the following code:
请考虑以下代码:
main(){\
return 0;
}
When I saw the pre-processed code(gcc -E
) it shows
当我看到预处理代码(gcc -E)时,它会显示出来
main(){return
0;
}
and not
main(){return 0;
}
What is the reason for this kind of behaviour? Also, how can I get the code I expected?
这种行为的原因是什么?另外,我如何获得我期望的代码?
3 个解决方案
#1
10
Yes, your expected result is the one required by the C and C++ standards. The backslash simply escapes the newline, i.e. the backslash-newline sequence is deleted.
是的,您的预期结果是C和C ++标准所要求的结果。反斜杠只是转义换行符,即删除反斜杠换行符序列。
GCC 4.2.1 from my OS X installation gives the expected result, as does Clang. Furthermore, adding a #define
to the beginning and testing with
我的OS X安装中的GCC 4.2.1给出了预期的结果,Clang也是如此。此外,在开头添加#define并使用
#define main(){\
return 0;
}
main()
yields the correct result
产生正确的结果
}
{return 0;
Perhaps gcc -E
does some extra processing after preprocessing and before outputting it. In any case, the line break seen by the rest of the preprocessor seems to be in the right place. So it's a cosmetic bug.
也许gcc -E在预处理之后和输出之前做了一些额外的处理。在任何情况下,预处理器其余部分看到的换行似乎都在正确的位置。所以这是一个美容虫。
UPDATE: According to the GCC FAQ, -E
(or the default setting of the cpp
command) attempts to put output tokens in roughly the same visual location as input tokens. To get "raw" output, specify -P
as well. This fixes the observed issues.
更新:根据GCC FAQ,-E(或cpp命令的默认设置)尝试将输出标记放在与输入标记大致相同的视觉位置。要获得“原始”输出,请同时指定-P。这解决了观察到的问题。
Probably what happened:
可能发生了什么:
- In preserving visual appearance, tokens not separated by spaces are kept together.
- Line splicing happens before spaces are identified for the above.
- The
{
andreturn
tokens are grouped into the same visual block. -
0
follows a space and its location on the next line is duly noted.
在保持视觉外观时,未被空格分隔的标记保持在一起。
在为上述标识空间之前发生线拼接。
{和返回令牌被分组到相同的视觉块中。
0跟随一个空格,并且它在下一行的位置被正确记录。
PLUG: If this is really important to you, I have implemented my own preprocessor with correct implementation of both raw-preprocessed and whitespace-preserving "pretty" modes. Following this discussion I added line splices to the preserved whitespace. It's not really intended as a standalone tool, though. It's a testbed for a compiler framework which happens to be a fully compliant C++11 preprocessor library, which happens to have a miniature command-line driver. (The error messages are on par with GCC, or Clang, sans color, though.)
PLUG:如果这对你真的很重要,我已经实现了我自己的预处理器,正确实现了原始预处理和保留空白的“漂亮”模式。在讨论之后,我将线条拼接添加到保留的空白区域。但是,它并不是真正的独立工具。它是编译器框架的测试平台,恰好是一个完全兼容的C ++ 11预处理器库,恰好有一个微型命令行驱动程序。 (但错误消息与GCC相同,或者Clang,没有颜色。)
#2
10
From K&R section A.12 Preprocessing:
来自K&R部分A.12预处理:
A.12.2 Line Splicing
A.12.2线拼接
Lines that end with the backslash character \ are folded by deleting the backslash and the following newline character. This occurs before division into tokens.
以反斜杠字符\结尾的行通过删除反斜杠和以下换行符来折叠。这在分成令牌之前发生。
#3
4
It doesn't matter :/ The tokenizer will not see any difference. 1
没关系:/令牌化器不会看到任何差异。 1
Update In response to the comments:
更新回应评论:
There seems to be a fair amount of confusion as to what the expected output of the preprocessor should be. My point is that the expectation /seems/ reasonable at a glance but doesn't actually need to be specified in this way for the output to be valid. The amount of whitespace present in the output is simply irrelevant to the parser. What matters is that the preprocessor should treat the continued line as one line while interpreting it.
关于预处理器的预期输出应该是什么,似乎存在相当大的混淆。我的观点是期望/似乎/合理一目了然但实际上并不需要以这种方式指定输出有效。输出中存在的空白量与解析器无关。重要的是预处理器应该在解释它时将续行视为一行。
In other words: the preprocessor is not a text transformation tool, it's a token manipulation tool.
换句话说:预处理器不是文本转换工具,它是一个令牌操作工具。
If it matters to you, you're probably
如果对你很重要,你很可能
- using the preprocessor for for something other than C/C++
- treating C++ code as text, which is a ... code smell. (libclang and various less complete parser libraries come to mind).
使用预处理器来处理C / C ++以外的东西
将C ++代码视为文本,这是一种代码味道。 (脑海中浮现了libclang和各种不太完整的解析器库)。
1 (The preprocessor is free to achieve the specified result in whichever way it sees fit. The result you are seeing is possibly the most efficient way the implementors have found to implement this particular transformation)
1(预处理器可以按照它认为合适的方式*地实现指定的结果。您看到的结果可能是实现者实现此特定转换的最有效方式)
#1
10
Yes, your expected result is the one required by the C and C++ standards. The backslash simply escapes the newline, i.e. the backslash-newline sequence is deleted.
是的,您的预期结果是C和C ++标准所要求的结果。反斜杠只是转义换行符,即删除反斜杠换行符序列。
GCC 4.2.1 from my OS X installation gives the expected result, as does Clang. Furthermore, adding a #define
to the beginning and testing with
我的OS X安装中的GCC 4.2.1给出了预期的结果,Clang也是如此。此外,在开头添加#define并使用
#define main(){\
return 0;
}
main()
yields the correct result
产生正确的结果
}
{return 0;
Perhaps gcc -E
does some extra processing after preprocessing and before outputting it. In any case, the line break seen by the rest of the preprocessor seems to be in the right place. So it's a cosmetic bug.
也许gcc -E在预处理之后和输出之前做了一些额外的处理。在任何情况下,预处理器其余部分看到的换行似乎都在正确的位置。所以这是一个美容虫。
UPDATE: According to the GCC FAQ, -E
(or the default setting of the cpp
command) attempts to put output tokens in roughly the same visual location as input tokens. To get "raw" output, specify -P
as well. This fixes the observed issues.
更新:根据GCC FAQ,-E(或cpp命令的默认设置)尝试将输出标记放在与输入标记大致相同的视觉位置。要获得“原始”输出,请同时指定-P。这解决了观察到的问题。
Probably what happened:
可能发生了什么:
- In preserving visual appearance, tokens not separated by spaces are kept together.
- Line splicing happens before spaces are identified for the above.
- The
{
andreturn
tokens are grouped into the same visual block. -
0
follows a space and its location on the next line is duly noted.
在保持视觉外观时,未被空格分隔的标记保持在一起。
在为上述标识空间之前发生线拼接。
{和返回令牌被分组到相同的视觉块中。
0跟随一个空格,并且它在下一行的位置被正确记录。
PLUG: If this is really important to you, I have implemented my own preprocessor with correct implementation of both raw-preprocessed and whitespace-preserving "pretty" modes. Following this discussion I added line splices to the preserved whitespace. It's not really intended as a standalone tool, though. It's a testbed for a compiler framework which happens to be a fully compliant C++11 preprocessor library, which happens to have a miniature command-line driver. (The error messages are on par with GCC, or Clang, sans color, though.)
PLUG:如果这对你真的很重要,我已经实现了我自己的预处理器,正确实现了原始预处理和保留空白的“漂亮”模式。在讨论之后,我将线条拼接添加到保留的空白区域。但是,它并不是真正的独立工具。它是编译器框架的测试平台,恰好是一个完全兼容的C ++ 11预处理器库,恰好有一个微型命令行驱动程序。 (但错误消息与GCC相同,或者Clang,没有颜色。)
#2
10
From K&R section A.12 Preprocessing:
来自K&R部分A.12预处理:
A.12.2 Line Splicing
A.12.2线拼接
Lines that end with the backslash character \ are folded by deleting the backslash and the following newline character. This occurs before division into tokens.
以反斜杠字符\结尾的行通过删除反斜杠和以下换行符来折叠。这在分成令牌之前发生。
#3
4
It doesn't matter :/ The tokenizer will not see any difference. 1
没关系:/令牌化器不会看到任何差异。 1
Update In response to the comments:
更新回应评论:
There seems to be a fair amount of confusion as to what the expected output of the preprocessor should be. My point is that the expectation /seems/ reasonable at a glance but doesn't actually need to be specified in this way for the output to be valid. The amount of whitespace present in the output is simply irrelevant to the parser. What matters is that the preprocessor should treat the continued line as one line while interpreting it.
关于预处理器的预期输出应该是什么,似乎存在相当大的混淆。我的观点是期望/似乎/合理一目了然但实际上并不需要以这种方式指定输出有效。输出中存在的空白量与解析器无关。重要的是预处理器应该在解释它时将续行视为一行。
In other words: the preprocessor is not a text transformation tool, it's a token manipulation tool.
换句话说:预处理器不是文本转换工具,它是一个令牌操作工具。
If it matters to you, you're probably
如果对你很重要,你很可能
- using the preprocessor for for something other than C/C++
- treating C++ code as text, which is a ... code smell. (libclang and various less complete parser libraries come to mind).
使用预处理器来处理C / C ++以外的东西
将C ++代码视为文本,这是一种代码味道。 (脑海中浮现了libclang和各种不太完整的解析器库)。
1 (The preprocessor is free to achieve the specified result in whichever way it sees fit. The result you are seeing is possibly the most efficient way the implementors have found to implement this particular transformation)
1(预处理器可以按照它认为合适的方式*地实现指定的结果。您看到的结果可能是实现者实现此特定转换的最有效方式)