小编PSk*_*cik的帖子

枚举常量在C和C++中表现不同

为什么这样:

#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.

这种差异的理由是什么?

c c++

81
推荐指数
6
解决办法
4529
查看次数

为什么不自动假设#pragma?

告诉编译器只包含一次文件有什么意义?默认情况下它不会有意义吗?是否有任何理由多次包含单个文件?为什么不假设呢?是与特定硬件有关吗?

c c++ pragma

75
推荐指数
6
解决办法
6039
查看次数

`-rdynamic'究竟做了什么以及何时需要它?

究竟是什么-rdynamic(或--export-dynamic在链接器级别)做什么以及它如何与由-fvisibility*标志或可见性pragmas和__attribute__s 定义的符号可见性相关?

对于--export-dynamic,ld(1)提到:

...如果使用"dlopen"加载需要引用程序定义的符号的动态对象,而不是某些其他动态对象,则在链接程序本身时可能需要使用此选项....

我不确定我完全明白这一点.能否请您提供一个例子,如果没有它可以工作-rdynamic但是没有它?

编辑:我实际上尝试编译了几个虚拟库(单个文件,多个文件,各种-O级别,一些函数间调用,一些隐藏符号,一些可见),有和没有-rdynamic,到目前为止我一直在字节相同的输出(当然保持所有其他标志不变),这是非常令人费解的.

c gcc shared-libraries elf dynamic-loading

38
推荐指数
4
解决办法
2万
查看次数

void*总是与char*具有相同的表示吗?

将一个void*总是有相同的表示为char*

细节:

我想使用一个可变参数函数,它使char*被(char*)0类似的终止:

int variadic(char*, ...); //<-prototype
variadic("foo", "bar", (char*)0); //<- usage
Run Code Online (Sandbox Code Playgroud)

我想,以取代(char*)0NULL,但是从判断 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*,...)吗?

c pointers language-lawyer

24
推荐指数
2
解决办法
1465
查看次数

结构的成员名称中的前缀

考虑

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)

c linux

19
推荐指数
1
解决办法
2920
查看次数

STL中的继承问题

http://www.stepanovpapers.com/notes.pdf中,Alexander Stepanov提到:

有趣的是,STL中保留的唯一继承示例继承自空类.最初,在容器甚至迭代器中有许多继承用途,但由于它们引起的问题,它们必须被删除.

哪些技术问题妨碍了在STL中使用继承?

c++ inheritance stl

15
推荐指数
1
解决办法
374
查看次数

是否必须对退出函数进行noreturn属性?

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 language-lawyer c11

12
推荐指数
1
解决办法
168
查看次数

为什么shell会在后台进程中忽略SIGINT和SIGQUIT?

如果我在脚本或-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)

unix linux shell posix signals

11
推荐指数
1
解决办法
769
查看次数

为什么每次执行时函数的地址都不同?

可执行代码的地址是在链接时决定的,不是吗?

#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)

c c++

11
推荐指数
2
解决办法
698
查看次数

检测宏参数是否为类型名

在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)。

c gcc clang c11

10
推荐指数
1
解决办法
110
查看次数