在3.0.4 Linux内核中,mm/filemap.c有这行代码:
retval = retval ?: desc.error;
Run Code Online (Sandbox Code Playgroud)
我已经尝试用gcc -Wall编译一个类似的最小测试用例,并且没有得到任何警告; 行为似乎与:
retval = retval ? retval : desc.error;
Run Code Online (Sandbox Code Playgroud)
看看C99标准,我无法弄清楚正式描述这种行为的原因.为什么这样好?
背景:我分配我自己的机器环境和堆栈与getcontext(3)
/ makecontext(3)
/ setcontext(3)
(ucontext.h
; SUSv2,POSIX.1-2001)系列函数.
当我使用gdb(版本6.1.1)检查堆栈而线程处于我分配的这些上下文之一时,似乎gdb不知道堆栈的结束(逻辑底部)在哪里.例如,这是来自x86 FreeBSD的堆栈:
#0 0x2872d79f in poll () from /lib/libc.so.7
#1 0x28646e23 in poll () from /lib/libthr.so.3
#2 0x2869b267 in fdtask (task=0x28a3dc40, v=0x0) at fd.c:58
#3 0x2869c8dc in taskstart (y=681827392, x=0) at task.c:58
#4 0x00000000 in ?? ()
#5 0x28a3dc40 in ?? ()
#6 0x00000000 in ?? ()
#7 0x00000000 in ?? ()
…
#65 0x00000000 in ?? ()
…
Run Code Online (Sandbox Code Playgroud)
(是的,这是建立在Russ Cox的libtask库之上的.)
这个上下文的执行从taskstart
函数开始,但似乎GDB无法弄清楚它应该停止尝试读取堆栈,即使它在该帧中遇到NULL的返回地址.
我的问题是:我能做些什么(通过以某种方式格式化堆栈,或设置寄存器,任何东西)来帮助GDB了解堆栈顶部的位置?谢谢.
编辑:结论:似乎gdb 6.1.1检测到堆栈结束的一种方法是检查存储的帧指针是否为NULL; …
void main()
{
int x=5;
printf("%d%d%d \n",x,x<<2,x>>2);
}
Run Code Online (Sandbox Code Playgroud) 我遇到了一些测试代码,它直接在终端上执行时提供不同的输出,当它的输出重定向到文件时:
# include <stdio.h>
# include <stdlib.h>
int main()
{
printf("hello\n");
if(fork() ==0)
{
printf("world\n");
}
}
Run Code Online (Sandbox Code Playgroud)
在终端上输出是:
abhi@ubuntu:~/Desktop/ad/A1/CC$ ./vb
hello
abhi@ubuntu:~/Desktop/ad/A1/CC$ world
Run Code Online (Sandbox Code Playgroud)
(打印世界后光标仍然闪烁,输入后显示正常提示.)
在将输出重定向到文件时:
./vb >v.txt
abhi@ubuntu:~/Desktop/ad/A1/CC$ cat v.txt
hello
hello
world
Run Code Online (Sandbox Code Playgroud)
据我所知,父母不等孩子就打印hello
并返回.然后孩子应该打印world
,代码应该终止.
我无法理解的是,为什么代码在重定向输出时表现不同.这是什么原因?