为什么这样:
#include <stdio.h>
#include <limits.h>
#include <inttypes.h>
int main() {
enum en_e {
en_e_foo,
en_e_bar = UINT64_MAX,
};
enum en_e e = en_e_foo;
printf("%zu\n", sizeof en_e_foo);
printf("%zu\n", sizeof en_e_bar);
printf("%zu\n", sizeof e);
}
Run Code Online (Sandbox Code Playgroud)
4 8 8用C和8 8 8C++ 打印(在4字节整数的平台上)?
我的印象是,UINT64_MAX赋值将强制所有枚举常量至少为64位,但en_e_foo在纯C中保持为32.
这种差异的理由是什么?
告诉编译器只包含一次文件有什么意义?默认情况下它不会有意义吗?是否有任何理由多次包含单个文件?为什么不假设呢?是与特定硬件有关吗?
究竟是什么-rdynamic(或--export-dynamic在链接器级别)做什么以及它如何与由-fvisibility*标志或可见性pragmas和__attribute__s 定义的符号可见性相关?
对于--export-dynamic,ld(1)提到:
...如果使用"dlopen"加载需要引用程序定义的符号的动态对象,而不是某些其他动态对象,则在链接程序本身时可能需要使用此选项....
我不确定我完全明白这一点.能否请您提供一个例子,如果没有它可以工作-rdynamic但是没有它?
编辑:我实际上尝试编译了几个虚拟库(单个文件,多个文件,各种-O级别,一些函数间调用,一些隐藏符号,一些可见),有和没有-rdynamic,到目前为止我一直在字节相同的输出(当然保持所有其他标志不变),这是非常令人费解的.
将一个void*总是有相同的表示为char*?
细节:
我想使用一个可变参数函数,它使char*被(char*)0类似的终止:
int variadic(char*, ...); //<-prototype
variadic("foo", "bar", (char*)0); //<- usage
Run Code Online (Sandbox Code Playgroud)
我想,以取代(char*)0用NULL,但是从判断
http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1570.pdf的:
66)宏NULL在(和其他头部)中定义为空指针常量; 见7.19.
3值为0的整型常量表达式或类型为void*的表达式称为空指针常量.66)如果将空指针常量转换为指针类型,则保证将结果指针(称为空指针)与指向任何对象或函数的指针进行比较.
我不能,因为在variadic上下文中,我绝对需要char*一个平原0是不可接受的.
如果我定义:
#define NIL (void*)0 /*<= never a plain 0*/
Run Code Online (Sandbox Code Playgroud)
用它来终止我是合法的variadic(char*,...)吗?
考虑
struct iovec {
ptr_t iov_base; /* Starting address */
size_t iov_len; /* Length in bytes */
};
Run Code Online (Sandbox Code Playgroud)
要么
struct stat {
dev_t st_dev; /* ID of device containing file */
ino_t st_ino; /* inode number */
mode_t st_mode; /* protection */
nlink_t st_nlink; /* number of hard links */
uid_t st_uid; /* user ID of owner */
gid_t st_gid; /* group ID of owner */
dev_t st_rdev; /* device ID (if special file) */
off_t st_size; /* total size, …Run Code Online (Sandbox Code Playgroud) 在http://www.stepanovpapers.com/notes.pdf中,Alexander Stepanov提到:
有趣的是,STL中保留的唯一继承示例继承自空类.最初,在容器甚至迭代器中有许多继承用途,但由于它们引起的问题,它们必须被删除.
哪些技术问题妨碍了在STL中使用继承?
noreturn永不归还函数的属性是否必要,或者这只是一个(可能是不成熟的? - 至少对于退出,我无法想象为什么要优化)优化?
向我解释说,在诸如此类的背景下
void myexit(int s) _Noreturn {
exit(s);
}
// ...
if (!p) { myexit(1); }
f(*p);
/// ...
Run Code Online (Sandbox Code Playgroud)
noreturn防止!p分支被优化.但是编译器是否真的允许优化该分支?我意识到优化它的基本原理是:"未定义的行为不会发生.如果p== NULL,则解除引用它是UB,因此p永远不会NULL在此上下文中,因此!p分支不会触发".但是编译器不能通过假设myexit可能是一个不返回的函数来解决问题(即使它没有明确标记为这样)?
如果我在脚本或-c片段中处理进程,则后台进程会忽略SIGINT和SIGQUIT:
例:
$ alias ps='ps -o pid,ppid,pgrp,sid,stat,tty,ignored,blocked,caught,wchan,min_flt,pmem,args --forest'
$ sh -c 'sleep 1000 & sleep 1000 | sleep 1000' & \
sleep 0.01; ps |grep -v -e ps -e grep
PID PPID PGRP SID STAT TT IGNORED BLOCKED CAUGHT WCHAN MINFL %MEM COMMAND
6197 2143 6197 6197 Ss pts/28 0000000000380004 0000000000010000 000000004b817efb wait 10039 0.0 -bash
7593 6197 7593 6197 S pts/28 0000000000000000 0000000000000000 0000000000010002 wait 148 0.0 \_ sh -c sleep 1000 & sleep 1000 | sleep 1000
7595 …Run Code Online (Sandbox Code Playgroud) 可执行代码的地址是在链接时决定的,不是吗?
#include <stdio.h>
int main ()
{
printf("%p", (void*)&main);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
示例输出 #1:
0x563ac3667139
Run Code Online (Sandbox Code Playgroud)
示例输出 #2:
0x55e3903a9139
Run Code Online (Sandbox Code Playgroud) 在C11 / gnuC11中,可以编写一个宏,该宏分别返回值1或0的整数常量表达式,如果该宏参数是或不是类型名称,或者至少一个宏可以区分整数常量表达式和类型名称(即,如果可以检测到参数不是其中之一,则可以假设是另一个)?
#define IS_TYPENAME(X) /*???*/
_Static_assert( IS_TYPENAME(int), "" );
_Static_assert( !IS_TYPENAME(42), "" );
Run Code Online (Sandbox Code Playgroud)
动机:
我的动机是用_Alignas 包装一个宏,如果建议的对齐方式(类型或整数表达式)小于当前_Alignas对齐方式(正常且对齐方式较小会导致错误),则该宏将不执行任何操作,因此我也想接受类型名称或整数expr,但现在我想简单地要求使用整数expr(您可以始终通过应用来从类型名称中获取整数_Alignof)。