首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >cc和c++之间snprintf格式"%zu“的奇数结果

cc和c++之间snprintf格式"%zu“的奇数结果
EN

Stack Overflow用户
提问于 2017-10-27 09:48:48
回答 1查看 264关注 0票数 0
代码语言:javascript
复制
#include <stdio.h>
#include <stdlib.h>

int main()
{
     char buf[100];
     snprintf(buf, sizeof(buf), "C %s %s %u %zu", "aaa","bbb",0,0);
     printf("%s\n", buf);
}

cc -o测试测试

C aaa血bbb 0 140733193388032

c++ -o测试测试

C aaa bbb 0 0

两个人有什么区别?

环境

  • Linux xxx 3.10.0-514.26.1.el7.x86_64 #1 SMP清华6月29日16:05:25 UTC 2017 x86_64 GNU/Linux
  • cc (GCC) 4.8.5 20160623 (红帽4.8.5-11)
  • c++ (GCC) 4.8.5 20160623 (红帽4.8.5-11)
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2017-10-30 00:42:47

您使用了错误的说明符-- %zu应该使用size_t类型的打印值,但您正在尝试打印int类型的值。从技术上讲,你的程序是错误的,它的行为是没有定义的。

现在,关于这里实际发生的事情,以及为什么你会看到这些结果。你必须了解64 ABI的以下情况

  • int类型为4个字节,而size_t类型为8个字节。
  • 函数参数通过寄存器rdirsirdxrcxr8r9传递,并以反向顺序在堆栈上传递进一步的值。
  • 堆栈上的参数应该对齐8个字节。

请记住,140733193388032是0x7fff00000000 (较低的4个字节是0)。

在您的情况下,编译器生成的代码是:

代码语言:javascript
复制
mov     DWORD PTR [rsp], 0      ; <-- seventh arg passed on stack
mov     r9d, 0                  ; <-- sixth arg
mov     r8d, OFFSET FLAT:.LC0   ; <-- fifth arg
mov     ecx, OFFSET FLAT:.LC1   ; <-- fourth arg
mov     edx, OFFSET FLAT:.LC2   ; <-- third arg
mov     esi, 100                ; <-- second arg
mov     rdi, rax                ; <-- first arg
mov     eax, 0
call    snprintf 

注意最后一个参数是如何使用4字节mov指令编写的。这意味着上面的4个字节没有被初始化,并且包含一些垃圾值。但是,由于您使用的是指定的%zu打印它,snprintf需要8个字节,在较低的4个字节中打印零,从上4个字节中输出垃圾。这也意味着这种行为只能在第七次和进一步的争论中才能注意到。

为什么gcc和gc++的产出是不同的?因为不同的运行时在启动时执行不同的代码。对于C运行时,它只是随机地在这个内存位置的上字节处有零,而C++运行时在那里存储了一些非零值。

要避免这种错误,请使用-Wformat参数,甚至用-Wall -Wextra编译代码。这将给您以下警告:

代码语言:javascript
复制
1.c: In function ‘main’:
1.c:7:47: warning: format ‘%zu’ expects argument of type ‘size_t’, but argument 7 has type ‘int’ [-Wformat=]
      snprintf(buf, sizeof(buf), "C %s %s %u %zu", "aaa","bbb",0,0);
                                             ~~^
                                             %u
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/46972186

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档