【问题标题】:No expected warning from GCCGCC 没有预期的警告
【发布时间】:2013-11-02 13:34:18
【问题描述】:

世界

我现在正在将一些 32 位 C 代码移植到 64 位平台。

对于以下代码,我认为当我添加选项
"-Wall -Wconversion -Wextra" 将代码编译为 64 位平台(x86_64 而不是 IA64)时,GCC 应该会发出警告。
但是,我没有收到任何警告...

int len = strlen(pstr);

奇怪的是,当我将代码更改为以下代码时,我可以得到关于“size_t”和“int”之间转换的警告

size_t sz = strlen(pstr);
int len = sz;

环境信息:

gcc 版本 4.4.7

Linux dev217 2.6.32-358.el6.x86_64 #1 SMP Fri Feb 22 00:31:26 UTC 2013 x86_64 x86_64 x86_64 GNU/Linux

有什么想法吗?

编辑: 我可以用一个非常简单的程序来验证这一点。

[jsun@/tmp]

[jsun@/tmp]cat test1.c

#include <stdio.h>
#include <string.h>
#include <unistd.h>

int main()
{

    int len = strlen("testllllll");

    printf("len is %d\n", len);

    return 0;
}

[jsun@/tmp]gcc -Wall -Wconversion -Wextra test1.c

[jsun@/tmp]

稍微修改一下代码后:

[jsun@/tmp]

[jsun@/tmp]cat test1.c

#include <stdio.h>
#include <string.h>
#include <unistd.h>

int main()
{
    size_t sz = strlen("test111111");
    int len = sz;;

    printf("len is %d\n", len);

    return 0;
}

[jsun@/tmp]gcc -Wall -Wconversion -Wextra test1.c

test1.c:在函数“main”中:

test1.c:8: 警告:从“size_t”转换为“int”可能会改变其值

[jsun@/tmp]

【问题讨论】:

  • 你也是#include 吗?如果你不这样做,隐式函数声明将返回 int。你能发布你的源文件和 gcc 输出吗?
  • 我已经把代码贴在原帖里了
  • 我现在没有编译器来测试这个,但你可以尝试改变它来调用 strlen() 从 main(int argc, char *argv[]) 传入的参数看看它是否产生警告(例如strlen(argv[1]))。编译器可以将 strlen(conststring) 优化为精确值(在您的示例中为 10),甚至不包括对 strlen 的调用。在这种情况下,它可能不会导致警告。
  • 对于您的两个代码示例(gcc 4.7.3),我都收到了相同的警告(在正确的行上)。
  • @MarkWilkins 所说的。我用 gcc4.8.1 对此进行了测试,它都优化了对 strlen 的调用并报告了一个警告,两者都使用 -O0 和 -O2

标签: c linux gcc 32bit-64bit


【解决方案1】:

gcc 优化了 strlen() 函数,因为它对 const 字符串进行操作(结果在编译时已知)。它可能会用 const 数字替换结果,因此这里不进行强制转换。

更新:参考 http://gcc.gnu.org/onlinedocs/gcc-4.4.7/gcc/Other-Builtins.html

所以 strlen 和许多其他函数都是内置函数,除非指定了 -fno-builtin(或为单个函数指定了 -fno-builtin-function)。 您可以将 -fno-builtin-strlen 添加到您的 gcc 选项中。如果有铸造,它应该在铸造时发出警告。 或者您可以尝试使用带有 strlen() 的变量。 gcc 不会优化它

【讨论】:

  • 刚刚检查过 - 这是真的!如果我用 argv[1] 替换 OPs 示例中的 const 字符串,我会收到预期的警告
  • 哦,是的,我也检查了这个。如果在编译时可以知道结果,则 Gcc 会优化 strlen() 函数,尽管指定了 -O0。
猜你喜欢
  • 2019-03-15
  • 2021-08-08
  • 2019-08-06
  • 1970-01-01
  • 1970-01-01
  • 2023-03-12
  • 2022-08-17
  • 2010-11-29
  • 1970-01-01
相关资源
最近更新 更多