在 Clang 中使“函数调用中的参数过多”成为错误
Making `too many arguments in call to function` an error in Clang
我正在尝试使编译器警告 warning: too many arguments in call to 'IF'
成为一个错误(其中 IF
是一个函数)。
我在配置 clang 时遇到问题,因为我无法确定警告的实际名称。
我尝试了以下方法:
clang -Werror=too-many-arguments main.c
warning: unknown warning option '-Werror=too-many-arguments'; did you mean '-Werror=unknown-argument'?
[-Wunknown-warning-option]
但这只会产生上面的警告。
与
clang -Werror main.c
该警告确实变成了一个错误,但我试图只将这个特定的警告变成一个错误。
如何找到此编译器警告的名称以便将其升级为编译器错误?
谢谢。
-Werror
正在将 所有 警告变成错误。您可以关闭除您感兴趣的那个特定警告之外的所有警告,但这在很多层面上都是错误的,我只是出于学术原因才提到它。
您也可以考虑获得一个好的 lint,例如 Gimpel 的 FlexeLint 产品。这是一个带有完全可配置的警告、错误和信息性消息的 lint。
我检查了 Subversion 中的当前源并发现:test/Misc/warning-flags.c
在 Clang 源列表 warn_call_wrong_number_of_arguments
(此警告的内部代码),这意味着预计此警告没有单独的 -W
标志。我确信 Clang 开发人员会接受一个为此选项引入明确名称的补丁。
但在此之前,-Werror
是您唯一的选择。
这并没有直接回答您的问题,但我相信我可以提供比您正在寻找的更好的解决方案。
这个:
void test () {
printf("test\n");
}
是一个老式的非原型函数定义。作为定义,它指定函数没有参数,但作为声明,它不指定任何预期参数的数量和类型。鉴于此定义,错误传递参数(如 test("test")
或 test(42)
)的调用不违反约束并且不需要诊断,即使这样的调用在被评估时具有未定义的行为。
clang 超越了语言要求,警告您有关错误的调用。 (我有点惊讶它这样做了。例如,gcc 就没有。)
这正是 1989 年将原型添加到语言中的原因。正如您在问题中提到的,您可以这样定义函数:
void test(void) {
printf("test\n");
}
鉴于此定义是可见的,符合标准的编译器必须诊断出任何使用一个或多个参数错误地调用此函数的尝试。
您的问题的解决方案不是诱使编译器诊断语言不需要它诊断的问题。这是为了修复代码。很少有很好的理由不对所有函数声明和定义使用原型。
旧式声明和定义过时,但即使在 2011 版 ISO C 中它们仍然合法。(我个人认为这很不幸。)
(你说你不想指定void
作为参数,但你没有解释原因。)
我正在尝试使编译器警告 warning: too many arguments in call to 'IF'
成为一个错误(其中 IF
是一个函数)。
我在配置 clang 时遇到问题,因为我无法确定警告的实际名称。
我尝试了以下方法:
clang -Werror=too-many-arguments main.c
warning: unknown warning option '-Werror=too-many-arguments'; did you mean '-Werror=unknown-argument'?
[-Wunknown-warning-option]
但这只会产生上面的警告。
与
clang -Werror main.c
该警告确实变成了一个错误,但我试图只将这个特定的警告变成一个错误。
如何找到此编译器警告的名称以便将其升级为编译器错误?
谢谢。
-Werror
正在将 所有 警告变成错误。您可以关闭除您感兴趣的那个特定警告之外的所有警告,但这在很多层面上都是错误的,我只是出于学术原因才提到它。
您也可以考虑获得一个好的 lint,例如 Gimpel 的 FlexeLint 产品。这是一个带有完全可配置的警告、错误和信息性消息的 lint。
我检查了 Subversion 中的当前源并发现:test/Misc/warning-flags.c
在 Clang 源列表 warn_call_wrong_number_of_arguments
(此警告的内部代码),这意味着预计此警告没有单独的 -W
标志。我确信 Clang 开发人员会接受一个为此选项引入明确名称的补丁。
但在此之前,-Werror
是您唯一的选择。
这并没有直接回答您的问题,但我相信我可以提供比您正在寻找的更好的解决方案。
这个:
void test () {
printf("test\n");
}
是一个老式的非原型函数定义。作为定义,它指定函数没有参数,但作为声明,它不指定任何预期参数的数量和类型。鉴于此定义,错误传递参数(如 test("test")
或 test(42)
)的调用不违反约束并且不需要诊断,即使这样的调用在被评估时具有未定义的行为。
clang 超越了语言要求,警告您有关错误的调用。 (我有点惊讶它这样做了。例如,gcc 就没有。)
这正是 1989 年将原型添加到语言中的原因。正如您在问题中提到的,您可以这样定义函数:
void test(void) {
printf("test\n");
}
鉴于此定义是可见的,符合标准的编译器必须诊断出任何使用一个或多个参数错误地调用此函数的尝试。
您的问题的解决方案不是诱使编译器诊断语言不需要它诊断的问题。这是为了修复代码。很少有很好的理由不对所有函数声明和定义使用原型。
旧式声明和定义过时,但即使在 2011 版 ISO C 中它们仍然合法。(我个人认为这很不幸。)
(你说你不想指定void
作为参数,但你没有解释原因。)