c - 意外的函数行为

标签 c scope printf

首先是代码:

//functions
char dernier(char* s){
    return s[strlen(s)-1];
}

char* debut(char* s){
    s[strlen(s)-1] = '\0';
    return s;
}

//problematic bit :
printf("%s %s %c", debut(s), s, dernier(s)); //s = "test"

我预计输出为 tes tes s,但我得到的是 tes tes t,我觉得很奇怪。

知道为什么吗?谢谢!

最佳答案

C 标准没有强制规定函数参数的求值顺序。这完全取决于实现/ABI。

如果您使用的是无处不在的 x86-32,并且具有像 printf 这样的可变函数,那么您几乎肯定会使用调用约定 cdecl,其中参数被向右推送 -向左。这意味着 printf 调用站点附近的汇编代码很可能类似于(伪汇编代码):

push @s
call _dernier
push <ret val from _dernier>
push @s
push @s
call _debut
push <ret val from _debut>
push @format_string
call _printf

但是请注意,即使使用 cdecl 调用约定,所规定的只是参数的推送顺序。它们仍然可以按任何顺序求值,只要它们从右到左压入堆栈即可;您需要查看自己的编译器生成的汇编代码才能确定。

关于c - 意外的函数行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54408980/

相关文章:

python - 访问函数内的全局变量

c - printf() 'mysteriously' 如何知道我打算打印什么?

c - 我如何在 C 中格式化输出?

printf - 使用 printf 格式的变量

c - "The Heap"的确切性质

c - 内核项目des encryption

c - 硬件处理器计数器重置不正确

javascript - 为无父本地变量 : impossible? 定义 Setter/Getter

c - 将 argv[] 存储到两个数组中,用一个特殊的字符串分隔 (C)

javascript - 在 Javascript 中存储来自 AWS S3 SDK 的 listObject 数据