缩进#define
我知道#define
等通常不会缩进。 为什么?
我目前正在编写一些代码,其中混合了 #define
、#ifdef
、#else
、< code>#endif 等。所有这些通常与普通 C 代码混合在一起。 #define 的非缩进使得它们难以阅读。 缩进代码与非缩进#define 的混合是一场噩梦。
为什么#define 通常不缩进? 有没有理由不缩进(例如下面的代码)?
#ifdef SDCC
#if DEBUGGING == 1
#if defined (pic18f2480)
#define FLASH_MEMORY_END 0x3DC0
#elif defined (pic18f2580)
#define FLASH_MEMORY_END 0x7DC0
#else
#error "Can't set up flash memory end!"
#endif
#else
#if defined (pic18f2480)
#define FLASH_MEMORY_END 0x4000
#elif defined (pic18f2580)
#define FLASH_MEMORY_END 0x8000
#else
#error "Can't set up flash memory end!"
#endif
#endif
#else
#if DEBUGGING == 1
#define FLASH_MEMORY_END 0x7DC0
#else
#define FLASH_MEMORY_END 0x8000
#endif
#endif
I know that #define
s, etc. are normally never indented. Why?
I'm working in some code at the moment which has a horrible mixture of #define
s, #ifdef
s, #else
s, #endif
s, etc. All these often mixed in with normal C code. The non-indenting of the #define
s makes them hard to read. And the mixture of indented code with non-indented #define
s is a nightmare.
Why are #define
s typically not indented? Is there a reason one wouldn't indent (e.g. like this code below)?
#ifdef SDCC
#if DEBUGGING == 1
#if defined (pic18f2480)
#define FLASH_MEMORY_END 0x3DC0
#elif defined (pic18f2580)
#define FLASH_MEMORY_END 0x7DC0
#else
#error "Can't set up flash memory end!"
#endif
#else
#if defined (pic18f2480)
#define FLASH_MEMORY_END 0x4000
#elif defined (pic18f2580)
#define FLASH_MEMORY_END 0x8000
#else
#error "Can't set up flash memory end!"
#endif
#endif
#else
#if DEBUGGING == 1
#define FLASH_MEMORY_END 0x7DC0
#else
#define FLASH_MEMORY_END 0x8000
#endif
#endif
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(9)
ANSI C 之前的预处理器不允许行首和“#”字符之间有空格; 前导“#”必须始终放置在第一列中。
如今,ANSI 之前的 C 编译器已不存在。 使用您喜欢的任何样式(“#”之前的空格或“#”与标识符之间的空格)。
http://www.delorie.com/gnu/docs/gcc/cpp_48.html
Pre-ANSI C preprocessor did not allow for space between the start of a line and the "#" character; the leading "#" had to always be placed in the first column.
Pre-ANSI C compilers are non-existent these days. Use which ever style (space before "#" or space between "#" and the identifier) you prefer.
http://www.delorie.com/gnu/docs/gcc/cpp_48.html
正如一些人已经说过的,一些 Pre-ANSI 编译器要求 # 成为该行的第一个字符,但它们不要求附加预处理器指令,因此缩进是这样进行的。
我经常在旧的 Unix 标头中看到这种样式,但我讨厌它,因为语法着色在此类代码上经常失败。 我对预处理器指令使用了非常明显的颜色,以便它们脱颖而出(它们处于元级别,因此不应成为正常代码流的一部分)。
您甚至可以看到 SO 没有以有用的方式为序列着色。
As some have already said, some Pre-ANSI compilers required the # to be the first char on the line but they didn't require the preprocessor directive to be attached to it, so indentation was made this way.
I've often seen this style in old Unix headers but I hate it as the syntax coloring often fails on such code. I use a very visible color for pre-processor directives so that they stand out (they are at a meta-level so should not be part of the normal flow of code).
You can even see that SO does not color the sequence in a useful manner.
关于预处理器指令的解析,C99 标准(以及之前的 C89 标准)明确了编译器逻辑上执行的操作顺序。 特别是,我相信这意味着这段代码:
相当于:
无论好坏,带有 '-std=c89 -pedantic' 的 GCC 3.4.4 无论如何都接受带有注释的行。 我并不提倡将其作为一种风格——一秒钟也不提倡(这太可怕了)。 我只是认为这是可能的。
ISO/IEC 9899:1999 第 5.1.1.2 节翻译阶段说:
第 6.10 节预处理指令说:
唯一可能的争议是括号表达式“(在翻译阶段 4 开始时)”,这可能意味着散列之前的注释必须不存在,因为它们在第 4 阶段结束之前不会被空格替换
。值得注意的是,标准前的 C 预处理器在许多方面的行为并不统一,预处理器指令之前和之中的空格是不同编译器执行不同操作的领域之一,包括不识别前面带有空格的预处理器指令。
值得注意的是,反斜杠换行符删除发生在分析注释之前。
因此,您不应以反斜杠结束
//
注释。Regarding the parsing of preprocessor directives, the C99 standard (and the C89 standard before it) were clear about the sequence of operations performed logically by the compiler. In particular, I believe it means that this code:
is equivalent to:
For better or worse, GCC 3.4.4 with '-std=c89 -pedantic' accepts the comment-laden line, at any rate. I'm not advocating that as a style - not for a second (it is ghastly). I just think that it is possible.
ISO/IEC 9899:1999 section 5.1.1.2 Translation phases says:
Section 6.10 Preprocessing directives says:
The only possible dispute is the parenthetical expression '(at the start of translation phase 4)', which could mean that the comments before the hash must be absent since they are not otherwise replaced by spaces until the end of phase 4.
As others have noted, the pre-standard C preprocessors did not behave uniformly in a number of ways, and spaces before and in preprocessor directives was one of the areas where different compilers did different things, including not recognizing preprocessor directives with spaces ahead of them.
It is noteworthy that backslash-newline removal occurs before comments are analyzed.
Consequently, you should not end
//
comments with a backslash.我不知道为什么它不更常见。 有时我确实喜欢缩进预处理器指令。
一直困扰我的一件事(有时说服我停止尝试)是,许多或大多数编辑器/IDE 都会在最轻微的挑衅下将指令扔到第 1 列。 这真是太烦人了。
I don't know why it's not more common. There are certainly times when I like to indent preprocessor directives.
One thing that keeps getting in my way (and sometimes convinces me to stop trying) is that many or most editors/IDEs will throw the directive to column 1 at the slightest provocation. Which is annoying as hell.
现在我认为这主要是风格的选择。 我认为在遥远的过去的某个时刻,并非所有编译器都支持缩进预处理器定义的概念。 我做了一些研究,但无法支持这一说法。 但无论如何,似乎所有现代编译器都支持缩进预处理器宏的想法。 我没有 C 或 C++ 标准的副本,所以我不知道这是否是标准行为。
至于款式好不好。 就我个人而言,我喜欢将它们全部保留在左侧的想法。 它为您提供了一个一致的地方来寻找它们。 是的,当有非常嵌套的宏时,它会变得很烦人。 但如果你缩进它们,你最终会得到看起来更奇怪的代码。
These days I believe this is mainly a choice of style. I think at one point in the distant past, not all compilers supported the notion of indenting preprocessor defines. I did some research and was unable to back up that assertion. But in any case, it appears that all modern compilers support the idea of indenting pre-processor macro. I do not have a copy of the C or C++ standard though so I do not know if this is standard behavior or not.
As to whether or not it's good style. Personally, I like the idea of keeping them all to the left. It gives you a consistent place to look for them. Yeah it can get annoying when there are very nested macros. But if you indent them, you'll eventually end up with even weirder looking code.
对于您给出的示例,考虑到您有如此复杂的嵌套指令结构,使用缩进使其更清晰可能是合适的。
就我个人而言,我认为在大多数情况下保持它们不缩进是有用的,因为这些指令与代码的其余部分分开运行。 #ifdef 等指令是在编译器看到您的代码之前由预处理器处理的,因此 #ifdef 指令之后的代码块甚至可能不会被编译。
当指令散布在代码中时(而不是像您给出的示例中那样使用专用的指令块),保持指令在视觉上与代码的其余部分分开更为重要。
For the example you've given it may be appropriate to use indentation to make it clearer, seeing as you have such a complex structure of nested directives.
Personally I think it is useful to keep them not indented most of the time, because these directives operate separately from the rest of your code. Directives such as #ifdef are handled by the pre-processor, before the compiler ever sees your code, so a block of code after an #ifdef directive may not even be compiled.
Keeping directives visually separated from the rest of your code is more important when they are interspersed with code (rather than a dedicated block of directives, as in the example you give).
目前几乎所有可用的 C/CPP 编译器都没有限制。 由用户决定如何对齐代码。
编码如此快乐。
In almost all the currently available C/CPP compilers it is not restricted. It's up to the user to decide how you want to align code.
So happy coding.
一个常见的解决方案是对指令进行注释,以便您轻松了解它们所指的内容:
A common solution is to comment the directives, so that you easily know what they refer to:
我知道这是老话题,但我浪费了几天时间寻找解决方案。 我同意最初的文章,如果你有很多代码,那么打算使代码更清晰(在我的例子中,我使用指令来启用/禁用详细日志记录)。 最后,我在此处找到了适用于 Visual Studio 2017 的解决方案
剩下的唯一问题是自动代码布局修复了格式 =(
I know this is old topic but I wasted couple of days searching for solution. I agree with initial post that intending makes code cleaner if you have lots of them (in my case I use directives to enable/disable verbose logging). Finally, I found solution here which works Visual Studio 2017
The only problem left is that auto code layout fixed that formatting =(