为什么“函数名称”是在 C 中评估为 true 以及如何收到警告

发布于 2024-10-05 20:56:59 字数 703 浏览 2 评论 0原文

我最近偶然发现 gcc 3.2.2 编写 ac 程序的以下行为:

在 if 语句中我忘记了函数的大括号并写道:

if(myFunc)... 而不是 if (myFunc())...

尽管我几乎打开了每个警告,但这并没有生成错误,也没有生成警告。

它只是评估为true。 首先为什么要编写法律代码? 因为该函数存在/有一个地址? 有谁知道如何避免此类错误,或者是否有我忽略的警告选项?这个问题在以后的 gcc 版本中是否得到了更好的解决?

这里确切的编译器要求完整性:(

 msp430-gcc -g -Os -mmcu=msp430x1611 -Wall -W -Wfloat-equal -Wundef -Wshadow -Wpointer-arith -Wbad-function-cast -Wcast-qual -Wwrite-strings -Wsign-compare -Waggregate-return -Wstrict-prototypes -Wmissing-prototypes -Wmissing-declarations 
-Wredundant-decls -Wnested-externs -Wimplicit-function-declaration -Werror

因为我被迫使用 gcc 3.2.3,所以没有 -Wextra)

I recently stumbled across the following behaviour of gcc 3.2.2 writing a c program:

In an if statement I forgot the braces of a function and wrote:

if(myFunc)... instead of if(myFunc())...

This did not generate an error neither a warning although I have pretty much every warning turned on.

It simply evaluated to true.
Why is this writing legal code in the first place ?
Because the function exists/has an address ?
Does anyone know how one could avoid such mistakes or if there is a warning option I overlooked ? Is this issue better solved in later gcc versions ?

Here the exact compiler call for completeness:

 msp430-gcc -g -Os -mmcu=msp430x1611 -Wall -W -Wfloat-equal -Wundef -Wshadow -Wpointer-arith -Wbad-function-cast -Wcast-qual -Wwrite-strings -Wsign-compare -Waggregate-return -Wstrict-prototypes -Wmissing-prototypes -Wmissing-declarations 
-Wredundant-decls -Wnested-externs -Wimplicit-function-declaration -Werror

(Since I'm forced to use gcc 3.2.3 there is no -Wextra)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

梦醒灬来后我 2024-10-12 20:56:59

if (myFunc) 相当于 if (&myFunc),因此您正在测试函数的地址,该地址当然始终为非零,即真的。

使用 gcc 4.2.1 和 -Wall 我收到以下警告:

myfunc.c:11:警告:'myFunc' 的地址将始终评估为 'true'

if (myFunc) is equivalent to if (&myFunc), so you're testing the address of a function, which of course will always be non-zero, i.e. true.

With gcc 4.2.1 and -Wall I get the following warning:

myfunc.c:11: warning: the address of ‘myFunc’ will always evaluate as ‘true’

妄司 2024-10-12 20:56:59

myFunc 只是函数的内存地址,并且不为零。

您的 if 语句与编写几乎相同:

if (0x08451234) { ... }

作为非零值,它是 true

没有警告似乎是合适的,因为测试函数指针以查看它们是否为 NULL 是有效的,甚至有些常见。

myFunc is simply the memory address of the function, and is non-zero.

Your if-statement is pretty much the same as writing:

if (0x08451234) { ... }

And as a non-zero value, it is true.

No warning seems appropriate, as it is valid and even somewhat common to test function-pointers to see if they are NULL or not.

萌化 2024-10-12 20:56:59

myFunc,因为它的函数名称将始终评估为 true,因为它是一个指针。更具体地说,它必须是一个非空指针,因为您需要取消引用它。 null 指针的计算结果为 false

简而言之,编译器似乎没有办法告诉你你犯了一个错误。

您需要做的是进行一些单元测试,分别调用 truefalse 响应,以便您可以知道您实际上已经调用了该函数。

myFunc, since its the name of a function will always evaluate to true because its a pointer. More specifically it has to be a non-null pointer because you will be needing to dereference it. A null pointer would evaluate to false.

In short, there does not seem to be a way for the compiler to tell you that you've made a mistake.

What you need to do is to have some unit tests that separately invoke the true and false responses so that you can tell that you've actually called the function.

月牙弯弯 2024-10-12 20:56:59

指向函数的指针有时很有用 - 作为回调,例如在排序例程或数据捕获中。或者用于执行优化的计算转到类型例程,因为 C 没有模板。

但 99% 的情况下这是一个错误,较新的编译器会警告你

Pointers to functions are sometimes useful - as callbacks eg in sort routines or data capture. Or for doing optimized calculated-goto type routines, since C doesn't have templates.

But 99% of the time it's an error, newer compilers will warn you

私藏温柔 2024-10-12 20:56:59

这是为了支持旧的链接器 hack;许多编译器/链接器(包括 gcc 和 GNU binutils)允许您为计算结果为 0 的函数定义弱符号,除非链接的另一个目标文件/共享库覆盖该符号的值。 glibc 利用这个技巧来进行一些版本兼容性攻击。

This is to support an old linker hack; many compilers/linkers (including gcc and GNU binutils) allow you to define a weak symbol for a function which evaluates to 0 unless another object file/shared library that got linked overrides the value of the symbol. glibc makes use of this trick for some version-compatibility hacks.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文