C宏定义/#define的缩进问题?

12

我很好奇为什么我几乎看到所有的C宏都是这样格式化的:

#ifndef FOO
#   define FOO
#endif

或者这样:

#ifndef FOO
#define FOO
#endif

但绝不会出现这种情况:

#ifndef FOO
    #define FOO
#endif
此外,Vim的=操作符似乎只将前两项视为正确。这是由于编译器之间的可移植性问题,还是标准实践呢?
4个回答

7
我见过三种不同的做法,这只是风格而非语法问题。
通常情况下,第二个例子最为普遍,但我曾经看到有些情况下使用第一(或第三)种方式来区分多层 #ifdef。有时候逻辑嵌套得很深,如果想要一眼了解它,唯一的方法就是使用缩进,就像在代码块之间使用 { 和 } 进行缩进一样。

6
IIRC,旧版C预处理器要求#是行首字符(尽管我从未遇到过这种要求的预处理器)。
我从未见过你的第一个示例中的代码。通常我会像你的第二个示例一样编写预处理指令。我发现它对实际代码的缩进视觉干扰较小(尽管我不再写C代码了)。 GNU C Preprocessor manual指出:
预处理指令是程序中以“#”开头的行。在“#”前后允许有空格。

1
还有另一个令人烦恼的问题(就像 OP 在问题中提到的那样),编辑器通常会对预处理器条件块应该如何缩进(或不缩进)有自己的看法。 - Michael Burr
2
旧的VAX C编译器(约1986年)如果预处理指令不在第一列中没有#,则会抛出错误。 - John Bode

3

我更喜欢第三种风格,但包含保护除外,对于保护我使用第二种风格。

我不太喜欢第一种风格 - 我认为#define是预处理指令,即使实际上它不是,它是一个#后跟预处理指令define。但是由于我确实这样想,将它们分开似乎是错误的。我希望支持该风格的人编写的文本编辑器能够对该风格的代码进行块缩进/取消缩进。但是,如果使用不支持该风格的文本编辑器,则会感到非常不舒服。

除非您可以列出所有其他实现与标准C之间的区别,以避免可能不支持的其他操作,否则没有必要迎合古老的预处理器,其中#必须是行的第一个字符。当然,如果您真的正在使用早期的编译器,那就没问题。


1

预处理器指令是包含在我们程序中的行,它们实际上不是程序语句,而是预处理器的指令。这些行总是以井号(#)开头。在'#'之前和之后允许有空格。一旦发现换行符,预处理器指令就被认为结束。

就C/C++标准而言,没有其他规则,因此它仍然是样式和可读性问题,我只看到/编写了第二种你发布的方式,尽管第三种方式似乎更易读。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接