在严格的 C89 模式下编译器不会对 `uint64_t` 发出警告

问题描述 投票:0回答:1

我正在尝试编写严格的 ISO C89 兼容代码。由于

long long
不是标准的,并且通常在 C99 之前作为编译器扩展实现,因此当我使用它时,编译器应该警告我。但是,当使用 gcc 或 clang 时,使用
int64_t
并扩展为
long long
(使用 32 位编译
-m32
)时不会出现警告。有什么办法让编译器警告我吗?

例如:

/* test.c */
#include <stdint.h>
#include <stdio.h>
int main(void) {
    printf("The size of an int64_t is %u.\n", (unsigned)sizeof(int64_t));
    return 0;
}

使用 clang 或 gcc 编译:

clang-17 -m32 -std=c89 -Wall -Wextra -Werror -pedantic -pedantic-errors test.c
# or
x86_64-pc-linux-gnu-gcc-13.2.1 -m32 -std=c89 -Wall -Wextra -Werror -pedantic -pedantic-errors test.c

它们不会发出警告或错误,即使

int64_t
实际上是
long long int
的 typedef,因为
clang-17 -m32 -std=c89 -E -dD -Wall -Wextra -Werror -pedantic -pedantic-errors test.c
给了我:

...
#define __INT64_TYPE__ long long int
#define __INT64_FMTd__ "lld"
#define __INT64_FMTi__ "lli"
#define __INT64_C_SUFFIX__ LL
...

并且在

/path/to/clang/17/include/stdint.h
中有

...
#ifdef __INT64_TYPE__
# ifndef __int8_t_defined /* glibc sys/types.h also defines int64_t*/
typedef __INT64_TYPE__ int64_t;
# endif /* __int8_t_defined */
typedef __UINT64_TYPE__ uint64_t;
# undef __int_least64_t
...

但是如果我将上面

int64_t
中的
long long
替换为
__INT64_TYPE__
test.c
,编译器会抱怨它。那么为什么
long long
uint64_t
之间存在行为差异?

SO 上最相关的问题似乎是 thisthis,但他们的答案似乎并没有解释为什么使用

-m32
时没有警告。 (在
-m64
模式下,
uint64_t
不是问题,因为它扩展为
long
,这是 C89 标准中的)。

c gcc compiler-errors clang c89
1个回答
0
投票

代码仍然严格遵循。允许编译器或应用程序具有

#include <header.h>
风格的标头,即使它们不是标准库的一部分。鉴于这些标头中没有任何内容与严格遵守的程序相冲突。它们可能包含自定义类型。标识符
int64_t
等与严格符合 C89 实现中的任何内容都不会冲突。

header.h
(在本例中为
stdint.h
)在相应的实现文件中内部执行的操作与编译器无关,除非编译器也负责编译该代码(这不是必需的)。该库必须通过头文件提供 C 接口,但从那里实际库的实现可以是某种 lib 或目标文件格式的交付者。而这甚至不需要用 C 编写。

然而

long long
在 C89 中无效,因为
long
是保留关键字,因此某些第 3 方标头无法提供这样的标识符。

用 gcc 编译

-std=c89 -pedantic-errors
给出:

错误:ISO C90 不支持“long long”[-Wlong-long]

叮当:

错误:未启用 C99 模式时,'long long' 是扩展名 [-Werror,-Wlong-long]

至于

-m32
,这与标准一致性无关。只要
long
至少为 32 位,就符合要求。 32 位应用程序当然也可以支持 64 位类型,尽管 CPU 无法在单个指令中处理这些类型。

如果您仍然坚持出于某种原因阻止

int64_t
进行编译,您可以添加类似以下内容:

#pragma GCC poison int64_t
© www.soinside.com 2019 - 2024. All rights reserved.