我如何指示gcc警告我有关无效的函数指针转换,比如g ++会对下面的代码做什么?
并且..为什么gcc没有警告我这个?将指针传递给do_something()时会发生什么/将会发生什么?
#include <stdio.h>
typedef void (*void_func_t) ();
typedef void (*void_int_func_t) (int, int, int);
void do_something(void_func_t f)
{
void_int_func_t foo = f;
foo(1,2,3);
}
void a()
{
printf("a\n");
}
void b(int one, int two, int three)
{
printf("%i, %i, %i\n", one, two, three);
}
int main()
{
do_something(a);
do_something(b);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
输出:
? gcc -W -Wall -Werror func.c
? ./a.out
a
1, 2, 3
Run Code Online (Sandbox Code Playgroud)
然而,c ++会警告/给出错误
g++ -W -Wall -Werror func.c
func.c: In function ‘void do_something(void_func_t)’:
func.c:8:27: error: …Run Code Online (Sandbox Code Playgroud) 我有一些 C++ 代码,我可以在其中切换枚举中的值。我试图用 -Wall -Wextra -Werror 编译它。这在使用 clang 时很好。但是,GCC 抱怨未涵盖默认代码路径。简化版本如下所示:
enum class Types: int {
A,
B,
C
};
bool some_logic(Types val) {
switch (val) {
case Types::A:
return (false);
case Types::B:
return (true);
case Types::C:
return (false);
}
}
Run Code Online (Sandbox Code Playgroud)
我可以通过在函数末尾添加一个 default case 或另一个 return 语句来处理这个问题。但是,我的问题是为什么 GCC 没有检测到枚举的所有情况都已涵盖?或者换一种说法,海湾合作委员会在这里抱怨是否有正当理由?
我在此处对编译器输出进行了比较。
{
unsigned long long two16, two48 ;
two16 = 65536;
two48 = two16 * two16 * two16 ;
printf("2^48=%llX \n",two48 );
two48 = 1<<48 ;
printf("Shifted 1<<48=%llX \n",two48);
return 0 ;
}
Run Code Online (Sandbox Code Playgroud)
当在 64 位机器上编译时,字大小为 8,上面给出警告 2=1<<48 将溢出左移计数 >= 类型宽度。
程序的输出是:
2^48=1000000000000
Shifted 1<<48=0
Run Code Online (Sandbox Code Playgroud)
到底是怎么回事?为什么我不能将 64 位数量移至 48 位?
我试图将数组传递给方法。我尝试了以下方法:
\n我不明白为什么最后一个(#3)发出警告。&ARRAY_NAME 在 memset、memcpy 等中工作时没有警告。为什么它在自定义方法中存在问题?
\n警告信息:
\nfunctionTest.c:35:11: warning: passing argument 1 of \xe2\x80\x98func2\xe2\x80\x99 from incompatible pointer type [-Wincompatible-pointer-types]\n 35 | func2(&temp, ARRAY_SIZE);\n | ^~~~~\n | |\n | unsigned char (*)[200]\nfunctionTest.c:8:27: note: expected \xe2\x80\x98unsigned char *\xe2\x80\x99 but argument is of type \xe2\x80\x98unsigned char (*)[200]\xe2\x80\x99\n 8 | void func2(unsigned char* buf, int length)\nRun Code Online (Sandbox Code Playgroud)\n代码
\n#include <stdio.h>\n#include <stdint.h>\n#include <string.h>\n\n\n#define ARRAY_SIZE 200\n\nvoid …Run Code Online (Sandbox Code Playgroud) 我需要检查一个研究项目的 200 万个 C 源文件是否存在简单的语法错误,例如缺少(分号、括号等)。每个文件都是一个没有 main() 和头文件的函数。\n在 GCC 的帮助下,我使用了以下命令:
\ngcc -c -fsyntax-only -w file.c\nRun Code Online (Sandbox Code Playgroud)\n我的脚本正在完成这项工作,但唯一的问题是几乎超过 95% 的错误都与缺少头文件有关。我试图将其中一些头文件添加到每个函数中,但这些头文件的数量似乎无穷无尽。
\n有什么办法可以抑制丢失头文件的错误吗?
\nGCC 是否有一个可以用于我的目的的特殊标志?
\n与头文件相关的错误示例:
\nerror: unknown type name \xe2\x80\x98ioreq_t\xe2\x80\x99\nerror: unknown type name \xe2\x80\x98SH7750State\xe2\x80\x99\nerror: unknown type name \xe2\x80\x98int64_t\xe2\x80\x99\nerror: unknown type name \xe2\x80\x98AVCodecContext\xe2\x80\x99\nerror: unknown type name \xe2\x80\x98BlockDriverState\xe2\x80\x99\nerror: unknown type name \xe2\x80\x98PXA2xxLCDState\xe2\x80\x99\nRun Code Online (Sandbox Code Playgroud)\n另外,我很欣赏除了使用 GCC 之外的任何其他解决方案。
\n下面两个 lambda 函数哪一个是正确的?
#include <cstdlib>
extern constinit int exit_code { };
int main( )
{
auto lambda_1 { [ &exit_code ]( ) noexcept
{
exit_code = EXIT_FAILURE;
} };
auto lambda_2 { [ ]( ) noexcept
{
exit_code = EXIT_FAILURE;
} };
lambda_1( );
lambda_2( );
return exit_code;
}
Run Code Online (Sandbox Code Playgroud)
海湾合作委员会警告&exit_code:
#include <cstdlib>
extern constinit int exit_code { };
int main( )
{
auto lambda_1 { [ &exit_code ]( ) noexcept
{
exit_code = EXIT_FAILURE;
} };
auto lambda_2 …Run Code Online (Sandbox Code Playgroud) extern void myprint(unsigned char *);
static inline void
myfunc(unsigned char *buf)
{
for (unsigned int i = 0; i < 20; i++) {
buf[i] = i;
}
}
int
main(void)
{
unsigned char buf[10];
myfunc(buf);
myprint(buf);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
$ gcc.exe -O2 -pedantic -Wextra -Wall -Wstringop-overflow -Wuninitialized -Wunused -Warray-bounds=2 -Wformat-overflow -Wstringop-overread -g -c C:\temp\cb\main.c -o build\mingw\obj\main.o
$ gcc.exe -o build\mingw\test.exe build\mingw\obj\main.o build\mingw\obj\mod.o -O2
Run Code Online (Sandbox Code Playgroud)
$ gcc --version
gcc (i686-posix-sjlj-rev1, Built by MinGW-W64 project) 11.2.0
Copyright (C) 2021 Free Software Foundation, Inc. …Run Code Online (Sandbox Code Playgroud) 这里TEST是一个结构指针.结构包含整数.什么是正确的因素呢?TEST结构如下.我使用gcc作为编译器.
typedef struct TEST_HELP{
int value;
} *TEST, TEST_NODE;
Run Code Online (Sandbox Code Playgroud) 当在varargs上下文中使用作用域枚举时,它被定义为作为其基础类型传递,如" 我可以使用枚举类值作为varargs函数的参数吗? "中所解释的那样.据我所知,这是唯一的情况,其中一个范围的枚举将被隐式转换,就像一个无范围的枚举.
考虑这个程序:
enum Foo : char { F };
enum class Bar : char { B };
#include <cstdio>
int main()
{
return !std::printf("%c\n", Foo::F)
+ !std::printf("%c\n", Bar::B);
}
Run Code Online (Sandbox Code Playgroud)
编译器(g++版本6.3.0)对a的第一个打印很满意Foo,但是当我传递时,抱怨Bar:
0.cpp: In function ‘int main()’:
0.cpp:10:34: warning: format ‘%c’ expects argument of type ‘int’, but argument 2 has type ‘Bar’ [-Wformat=]
+ !printf("%c\n", Bar::B);
^
Run Code Online (Sandbox Code Playgroud)
g++版本4.8.2没有抱怨这个,但g++6.3.0确实(这就是为什么它现在关注我).当存在实质性不匹配时,两个版本都抱怨第一次打印,例如使用%f或%s,或者如果我Foo改为使用long底层类型; 这就是我启用的原因-Wformat.
我知道警告不是标准一致性问题,我知道如何更改我的代码以解决这些问题(例如,在如何 …
gcc-warning ×9
c ×6
gcc ×4
c++ ×3
arrays ×1
clang++ ×1
enum-class ×1
enums ×1
lambda ×1
pointers ×1
syntax-error ×1