You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

CMake中多种C标准设置方式的差异及警告问题咨询

CMake中四种C标准设置方式的区别及警告差异分析

首先看你给出的CMake代码示例:

project(Test C)
add_executable(test test.c)

target_compile_features(test PRIVATE c_std_90) # (1)
add_definitions(-std=c90)  # (2)
set (CMAKE_C_STANDARD 90)  # (3)

# 4a和4b功能等价
set_target_properties(test PROPERTIES C_STANDARD 90) # (4a)
set_property(TARGET test PROPERTY C_STANDARD 90)  # (4b)
set_property(TARGET test PROPERTY C_STANDARD_REQUIRED ON)

add_compile_options(-pedantic)

四种设置方式的核心区别

(1) target_compile_features(test PRIVATE c_std_90)

这是基于特性的标准控制,CMake不会直接向编译器传递-std=c90这类参数。它的核心逻辑是:检查目标代码是否仅使用了C90标准定义的编译特性,若代码用到了更高版本的特性(比如C99的long long),CMake会报错,但它不会强制编译器进入严格的C90模式——编译器可能仍处于默认的扩展兼容模式(比如GCC的gnu90),允许使用部分非标准扩展。

(2) add_definitions(-std=c90)

这是直接传递编译参数,本质是给所有编译目标添加-std=c90编译选项,强制编译器进入严格的C90标准模式。所有不符合C90的语法、特性都会被编译器标记,配合-pedantic会触发完整的标准合规警告。

(3) set(CMAKE_C_STANDARD 90)

这是全局默认标准设置,指定整个项目的默认C语言版本,但默认行为比较宽松:

  • CMake不会主动传递-std=c90,而是传递编译器的默认兼容模式参数(比如GCC的-std=gnu90),该模式允许使用编译器扩展(如long long);
  • 仅当同时设置CMAKE_C_STANDARD_REQUIRED ON和CMAKE_C_EXTENSIONS OFF时,CMake才会传递严格的-std=c90参数,强制标准合规检查。

(4) set_target_properties / set_property 设置C_STANDARD 90

这两个写法功能完全等价,是针对单个目标的标准属性设置:

  • 当配合C_STANDARD_REQUIRED ON时,CMake会向目标传递严格的-std=c90参数,强制编译器进入C90标准模式;
  • 相比全局设置,它只作用于指定目标,不会影响项目内其他目标。

为什么测试代码的警告差异会出现?

你的测试代码使用了C99才引入的long long常量1ull和格式符%llu,不符合C90标准,但不同设置的行为不同:

#include <stdio.h>

int main(int argc, char *argv[]) {
    printf("Hello world! %llu", 1ull);
    return 0;
}
  • (1)和(3)不触发警告:

    • (1)的target_compile_features只检查代码是否使用了C90不支持的编译特性,但不会强制编译器进入严格模式,编译器处于扩展兼容模式,允许long long这类语法;
    • (3)默认传递的是-std=gnu90,该模式允许编译器扩展,所以不会触发-Wlong-long警告。
  • (2)和(4)触发警告:

    • (2)直接传递-std=c90,编译器进入严格C90模式;
    • (4)因设置了C_STANDARD_REQUIRED ON,CMake传递了-std=c90,配合-pedantic选项,编译器会严格检查所有不符合C90的语法,因此触发use of C99 long long integer constant警告。

内容的提问来源于stack exchange,提问作者hko

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.05 03:38:21