Tag: c99

如何将字符串可移植转换为不常见的整数类型?

一些背景:如果我想用,例如, scanf()将字符串转换为标准整数类型,如uint16_t ,我将使用 SCNu16 ,如下所示: #include #include uint16_t x; char *xs = “17”; sscanf(xs, “%” SCNu16, &x); 但是像pid_t这样的更不常见的整数类型没有任何这样的东西; 仅支持普通的整数类型。 要转换为另一种方式,可移植printf()一个pid_t ,我可以将它转换为intmax_t并使用PRIdMAX ,如下所示: #include #include #include pid_t x = 17; printf(“%” PRIdMAX, (intmax_t)x); 但是,似乎没有办法将scan scanf()移植到pid_t 。 所以这是我的问题:如何便携? #include #include pid_t x; char *xs = 17; sscanf(xs, “%u”, &x); /* Not portable! pid_t might not be int! […]

所有指针都是从指向结构类型的指针派生的吗?

问题 是否所有指针都是从指向结构类型的指针派生的问题都不容易回答。 我认为这是一个重要问题,主要有以下两个原因。 A.缺少指向“任何”不完整或对象类型的指针,对方便的函数接口施加了限制,例如: int allocate(ANY_TYPE **p, size_t s); int main(void) { int *p; int r = allocate(&p, sizeof *p); } [ 完整代码示例 ] 指向“任何”不完整或对象类型的现有指针明确描述为: C99 §6.3.2.3 p1 : 指向void的指针可以转换为指向任何不完整或对象类型的指针。 […] 从指向“任何”不完整或对象类型的现有指针派生的指针,指向void的指针,严格地是指向void的指针,并且不需要使用从指向“任何”不完整的指针派生的指针进行转换或对象类型。 B.程序员根据他们对特定实现的经验,使用基于不需要的假设的约定,有意或无意地与指针的泛化相关,这种情况并不少见。 假设,例如可转换,可表示为整数或共享公共属性:对象大小,表示或对齐。 标准的话 根据C99 §6.2.5 p27 / C11 §6.2.5 p28 : […]所有指向结构类型的指针应具有相同的表示和对齐要求。 […] 其次是C99 TC3 Footnote 39 / C11 Footnote 48 : 相同的表示和对齐要求意味着可互换性作为函数的参数,函数的返回值和联合的成员。 […]

人们使用什么技术/策略来构建C(而不是C ++)中的对象?

我特别感兴趣的是在C语言中使用的对象,而不是构成解释语言核心的对象的实现,例如python。

在C中签名转换为未签名

是否保证以下工作或实施定义? unsigned int a = 4294967294; signed int b = a; gcc的b值为-2 。 从C99(§6.3.1.3/ 3)起,否则新签名类型无法在其中表示; 结果是实现定义的,或者引发实现定义的信号。

将受限制的指针指定给另一个指针是否合法,并使用第二个指针修改该值?

以下方法是否尊重“限制”合同? void fun(int* restrict foo) { int* bar = foo + 32; for (int i = 0; i < 32; ++i) *bar = 0; } 我的猜测是否定的,但我需要澄清一下。

为什么编译器在尝试修改char *字符串文字时没有检测到并产生错误?

假设以下两段代码: char *c = “hello world”; c[1] = ‘y’; 上面的那个不起作用。 char c[] = “hello world”; c[1] = ‘y’; 这一个。 关于第一个,我理解字符串“hello world”可能存储在只读存储器部分中,因此无法更改。 然而,第二个在堆栈上创建一个字符数组,因此可以进行修改。 我的问题是 – 为什么编译器不会检测到第一类错误? 为什么不是C标准的一部分? 这有什么特别的原因吗?

如何在C99中正确内联和使用内联函数? (构建失败)

在以下简化的example.c文件上执行cc -std=c99 example.c : inline void a() { } int main() { a(); return 0; } 得到我: 在函数`main’中: example.c :(。text + 0x7):对’a’的未定义引用 collect2:ld返回1退出状态 据我所知,这与C99标准的要求有关,要求在无法内联的情况下使用的每个内联非静态函数的另一个定义? 如果是这样的话,我猜我可以用static inline代替,但我不想让它在以后咬我,那么这里最好的做法是什么呢? 显然,我想坚持C99,我想内联一些function。 (是的,我知道编译器通常知道内联的内容而不被告知,但我有我的理由)

如何打印无符号整数的最大值?

我想打印4个字节的无符号整数的最大值。 #include “stdafx.h” #include “conio.h” int _tmain(int argc, _TCHAR* argv[]) { unsigned int x = 0xffffffff; printf(“%d\n”,x); x=~x; printf(“%d”,x); getch(); return 0; } 但我输出为-1和0.如何打印x = 4294967295?

GNU89,混合声明和循环初始声明

GCC和ICC的默认C语言是GNU89。 GNU89允许混合声明,例如 int i; i = 0; int j; 我推断(错误地)来自SO上的一些其他post,例如C:for loop int initial declaration ,这意味着我可以做到 for(int i=0; i<n; i++) 使用GNU89但是当我这样做时,我得到了 error: ‘for’ loop initial declarations are only allowed in C99 mode 显然,混合声明和循环初始声明不是一回事(即一个并不暗示另一个)。 如果我只能有一个,我宁愿有循环初始声明。 当然,我可以使用GNU99,但这不是重点。 默认值是GNU89,它已经破坏了一些C89规则(它还允许BCPL / C ++样式注释)。 是否存在允许混合声明而不是循环初始声明的一些基本原因?

-Wmissing-field-initializer使用指定的初始值设定项时

我正在使用GCC 4.6.2(Mingw)并使用-Wextra编译。 每当我使用指定的初始化程序时,我都会收到奇怪的警告。 对于以下代码 typedef struct { int x; int y; } struct1; typedef struct { int x; int y; } struct2; typedef struct { struct1 s1; struct2 s2[4]; } bug_struct; bug_struct bug_struct1 = { .s1.x = 1, .s1.y = 2, .s2[0].x = 1, .s2[0].y = 2, .s2[1].x = 1, .s2[1].y = 2, .s2[2].x = […]