为什么 clang 会发出警告:文件末尾未终止的 '#pragma pack (push, …)' ?

xml*_*lmx 4 c++ clangd

我在启用了clangd 的vscode 中创建了一个 main.cpp ,并将以下代码放入其中。

\n

clangd用警告消息警告第一行:

\n
\n

警告:文件末尾未终止的 \xe2\x80\x98#pragma pack (push, \xe2\x80\xa6)\xe2\x80\x99

\n
\n

main.cpp的全部内容:

\n
#pragma pack(push) // warning on this line\n#pragma pack(1)\nstruct A\n{\n    int   a;\n    short b;\n    char  c;\n};\n#pragma pack(pop)\n
Run Code Online (Sandbox Code Playgroud)\n

另请参阅: https: //releases.llvm.org/13.0.0/tools/clang/docs/DiagnosticsReference.html#wpragma-pack

\n

我认为这是 的一个非常常见的用法#pragma pack(push),我不明白为什么会生成警告。

\n

对我来说更奇怪的是,如果我在第一行之前添加分号,警告就会消失。

\n
;                  // Add a semicolon\n#pragma pack(push) // The warning disappears\n#pragma pack(1)\nstruct A\n{\n    int   a;\n    short b;\n    char  c;\n};\n#pragma pack(pop)\n
Run Code Online (Sandbox Code Playgroud)\n

背后的原因是什么?

\n

HC4*_*ica 6

这是 clangd 中的一个已知错误,可在https://github.com/clangd/clangd/issues/1167中进行跟踪。

请参阅该问题以了解当前发生这种情况的原因。


该问题中讨论的一个可能的解决方法是在编译指示上方添加一个虚拟声明,以强制 clangd 在编译指示之前结束文件的“前导码”区域,例如:

static_assert(true); // dummy declaration, ends the preamble
#pragma pack(push) // no warning!
#pragma pack(1)
struct A
{
    int   a;
    short b;
    char  c;
};
#pragma pack(pop)
Run Code Online (Sandbox Code Playgroud)

请注意,如果文件包含#include指令,出于性能原因,这些指令应保留在序言中:

#include <...>  // still in the preamble
static_assert(true); // dummy declaration, ends the preamble
#pragma pack(push) // no warning!
#pragma pack(1)
struct A
{
    int   a;
    short b;
    char  c;
};
#pragma pack(pop)

Run Code Online (Sandbox Code Playgroud)

.clangd另一种解决方法是使用包含以下内容的文件来抑制警告

Diagnostics:
    Suppress: pragma-pack
Run Code Online (Sandbox Code Playgroud)