storage size of ‘oldact’ isn’t known

本文探讨了GCC编译器在不同标准模式下对C99函数的支持情况,特别是使用-std=c99或--ansi选项时的行为差异,并对比了GCC在Linux与FreeBSD平台上的表现。
#include <signal.h>

int main()
{
struct sigaction act, oldact;
return 0;
}


dies with the message


testgcc4.c: In function ‘main’:
testgcc4.c:6: error: storage size of ‘act’ isn’t known
testgcc4.c:6: error: storage size of ‘oldact’ isn’t known


if I use -std=c99 or --ansi?
gcc testgcc4.c compiles without problem but adding -std=c99 or --ansi produces
the error message above (for any of gcc-3.4, gcc-4.0, gcc-4.1) but neither

icc nor gcc on FreeBSD has a problem with -std=c99 or --ansi


Sumarry:

use -std=gnu99 on linux if you need some C99 functions (e.g. strtof) but also want to use functions like sigaction and strtok_r

gcc on linux is stricter than gcc on FreeBSD (or icc on either FreeBSD or linux) concerning standards.
gcc -std=c99 on linux means: *only* recognize functions specified in the standard (no sigaction, no strtok_r etc)
gcc -std=c99 on FreeBSD or icc -std=c99 on either FreeBSD or linux means recognize functions specified in the standard. This corresponds more or less to -std=gnu99 on linux

PS. This trap seems to be quite common (e.g. discussions on debian-glibc about the "fact" that strtof is completely broken on linux). I would be grateful if somebody could point me to a good overview describing what standards compliance means for various OS/compiler+options/standards combinations.

在给出的代码上下文中,`newact.sa_flags = 0; int count = 0; pid_t pid = 0;` 这几行代码各自有着不同的含义和用途: ### `newact.sa_flags = 0;` `newact` 是一个 `struct sigaction` 类型的结构体变量,该结构体用于设置信号处理的行为。`sa_flags` 是这个结构体中的一个成员,用于指定信号处理的一些特殊标志。将 `sa_flags` 设置为 0,表示不使用任何特殊的信号处理标志。根据引用[3],如果不需要重置该给定信号的处理函数为缺省值,并且不需要阻塞该给定信号,那么必须将 `sa_flags` 清零。这样做可以避免因使用不必要的标志而可能产生的段错误,但同时也可能会造成信号丢失 [^3]。 ### `int count = 0;` 这行代码定义了一个整型变量 `count`,并将其初始值设置为 0。在后续的代码中,`count` 被用作一个计数器,用于控制程序中的某些逻辑。在引用[2]的代码中,`count` 用于判断是否需要恢复信号处理的原始设置,并杀死子进程。当 `count` 的值大于 3 时,程序会执行相应的操作 [^2]。 ### `pid_t pid = 0;` `pid_t` 是一种用于表示进程 ID 的数据类型。这行代码定义了一个 `pid_t` 类型的变量 `pid`,并将其初始值设置为 0。`pid` 变量用于存储 `fork()` 函数的返回值。`fork()` 函数用于创建一个新的子进程,它会返回两次:在父进程中返回子进程的 ID(一个正整数),在子进程中返回 0。通过检查 `pid` 的值,程序可以区分父进程和子进程,并执行不同的操作。在引用[2]的代码中,根据 `pid` 的值,父进程和子进程会执行不同的逻辑 [^2]。 ### 代码示例 ```c #include <stdio.h> #include <unistd.h> #include <stdlib.h> #include <signal.h> int main() { struct sigaction newact, oldact; /* 设置信号忽略 */ newact.sa_handler = SIG_IGN; sigemptyset(&newact.sa_mask); newact.sa_flags = 0; // 不使用特殊的信号处理标志 int count = 0; // 初始化计数器 pid_t pid = 0; // 初始化进程 ID 变量 sigaction(SIGINT, &newact, &oldact); // 原来的备份到 oldact 里面 pid = fork(); // 创建子进程 if (pid == 0) { while (1) { printf("I'm child gaga.......\n"); sleep(1); } return 0; } while (1) { if (count++ > 3) { sigaction(SIGINT, &oldact, NULL); // 备份回来 printf("pid = %d\n", pid); kill(pid, SIGKILL); // 父进程发信号,来杀死子进程 } printf("I am father .......... hahaha\n"); sleep(1); } return 0; } ```
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值