Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/70.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
“解决方案”;“全局范围中的分号”;无op C宏的警告 在一个可以作为C或C++构建的代码库中,我认为我会利用一个宏来利用 StistaSytRe>/Cuff>,它是以C++ 11或更高的方式构建的。_C_C89_Static Assert - Fatal编程技术网

“解决方案”;“全局范围中的分号”;无op C宏的警告 在一个可以作为C或C++构建的代码库中,我认为我会利用一个宏来利用 StistaSytRe>/Cuff>,它是以C++ 11或更高的方式构建的。

“解决方案”;“全局范围中的分号”;无op C宏的警告 在一个可以作为C或C++构建的代码库中,我认为我会利用一个宏来利用 StistaSytRe>/Cuff>,它是以C++ 11或更高的方式构建的。,c,c89,static-assert,C,C89,Static Assert,(注意:我知道,至少如果你愿意接受一个message参数——尽管它不会在任何地方都有效。但是为了便于讨论,让我们假设我有一些正当的需要使它不接受任何消息,并且至少在一些C构建中是不可操作的。) 下面是我尝试过的简单定义: #if defined(__cplusplus) && __cplusplus >= 201103L #define STATIC_ASSERT(cond) \ static_assert((cond), #cond) #else

(注意:我知道,至少如果你愿意接受一个message参数——尽管它不会在任何地方都有效。但是为了便于讨论,让我们假设我有一些正当的需要使它不接受任何消息,并且至少在一些C构建中是不可操作的。)

下面是我尝试过的简单定义:

#if defined(__cplusplus) && __cplusplus >= 201103L
    #define STATIC_ASSERT(cond) \
        static_assert((cond), #cond)
#else
    #define STATIC_ASSERT(cond)
#endif
宏中没有分号,目的是将其添加到调用站点。但在pedantic C警告设置下,此宏出现在全局范围内会导致:

错误:ISO C不允许额外的“;”在函数之外[-Werror=pedantic]


简单的解决方案似乎是从调用站点中去掉分号,并将其放在宏的C++11端。但我想知道:如何在全局范围内创建一个no-op宏,允许在调用站点使用分号(而不会与其他警告冲突)?

由于结构的正向声明可能会重复很多次,因此可以使用伪声明:

#define STATIC_ASSERT(cond) struct GlobalScopeNoopTrick
@JonathanLeffler说,这应该适用于较旧的编译器,即使是C11之前的编译器……但是:

“如果您有一个C90编译器,如果在中的语句后有一个静态断言,它会反对。这不是您主要关心的问题(如果静态断言也可以,则在文件范围内总是可以),但它不限于在文件范围内使用。尽管风险很低”

对于编译时可能不完全没有操作的相关情况,C11引入了重复typedef的功能。正如在节目之前关于C中静态断言的文章中所链接的那样,有一些方法可以使用行号或其他消歧器绕过旧C的typedef复制:

/* Standard indirection to allow concatenation after expansion */
#define CONCAT(a,b) CONCAT_(a,b)
#define CONCAT_(a,b) a##b

#if defined(__cplusplus) && __cplusplus >= 201103L
    #define STATIC_ASSERT(cond) \
        static_assert((cond), #cond)
#else
    #define STATIC_ASSERT(cond) typedef void CONCAT(dummy_unused_,__LINE__)
#endif

只要静态断言每行出现一个,标识符就不会相互冲突。

不需要
\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu。类型定义可能会重复,因此任何不使用的名称都可以;可以使用
typedef void VoidTypeKludge
。也可以使用
struct staticassertsubrogate
作为替换文本,这将适用于C11以前的编译器(此时可以重复typedef)。结构标记是否作为真正的结构类型存在并不重要。@JonathanLeffler-谢谢,我只是在检查C89.C11中的typedef重新定义规则。关于typedef名称的措辞可能会被重新定义,以表示与当前相同的类型是新的。@HostileFork-我在中编辑替代名称后不久退出。我把它标记为CW(在手机上唯一相对容易的东西)。如果你不介意的话,进行编辑。或者我以后再谈。
#定义静态断言(cond)void never_called()
--分号完成正向声明。@RaymondChen在某些编译器/警告组合中,似乎会多次收到关于正向函数声明的警告。您可以禁用它们,但假设它们存在是有充分理由的……下面的结构解决方案似乎不会触发任何警告。