【问题标题】:Is forcing the order/placement of a #include bad practice?是否强制订购/放置#include 不好的做法?
【发布时间】:2015-09-11 23:18:32
【问题描述】:
我有一些代码(下面的“core.h”)与几个不同的包装器一起使用。每个包装器都要求它具有不同大小的数组。目前我在包装头文件中使用#define 来指定该数组的大小,但是必须在包含头文件之前将#define 写入文件中。
/*wrapper1.h*/
#define ARR_SIZE 42 // this must be written before-
#include "core.h" // this to ensure correct operation
//...
/*wrapper2.h*/
#define ARR_SIZE 128
#include "core.h"
//...
/*core.h*/
#ifndef ARR_SIZE
#define ARR_SIZE 256 // default value
#endif
struct foo
{
char arr[ARR_SIZE];
//...
};
//...
这是不好的做法吗?如果有,有更好的选择吗?
【问题讨论】:
标签:
c
include
c-preprocessor
【解决方案1】:
如果 wrapper1.h 和 wrapper2.h 在同一个程序中使用(即如果你有一个源文件 #includes wrapper1.h 和另一个 #includes wrapper2.h,那么你不能使用同一个项目中的这两个源文件没有非常小心地避免问题 - 大多数做这种事情的人都没有那么小心)。这样做将违反一个定义规则(因为struct foo 在您的程序中将有多个定义)。根据 C 标准,这会导致未定义的行为。
如果你在不同的项目中使用wrapper#.h,是没有问题的。然而,这是一个等待发生的错误——例如,是什么阻止你在未来某个时间在同一个项目中使用 wrapper1.h 和 wrapper2.h?没什么,就是这样。结果将是您的程序中的问题(在最坏的情况下,间歇性运行时错误)可能很难追踪。
您需要问的问题是,为什么您需要在不同的包装器中使用不同的尺寸,以及真正的区别是什么。然后正确设计您的标题(以及受这些标题影响的功能)。代码(在这种情况下为头文件)重用可能会导致更多问题而不是更糟糕的问题,这就是其中之一。
【解决方案2】:
恕我直言,如果可能的话,我鼓励不要这样做。我已经看到 libs 这样做,并且试图找出问题所在而感到头疼。
MISRA 的一些规则鼓励您不要这样做。以规则 3-1-1 为例。