Tag: c99

C99的支持真的还没有普及吗?

我正在阅读GNOME项目的一些最佳实践,他们一直强调的一件事是避免C99function,因为支持仍然不普遍。 他们提到的一些function是单行注释和在块中间声明变量等function。 这让我很奇怪,是C99的支持,即使对于//评论这样的基本function,还真的还没有普及吗? 自标准通过以来已经差不多15年了,我们甚至在那个时候出现了新的标准。 这真的还是个问题吗?

为什么C中的复合文字可以修改

人们通常将“不可修改的”与术语“文字”联系起来 char* str = “Hello World!”; *str = ‘B’; // Bus Error! 然而,当使用复合文字时,我很快发现它们是完全可修改的(并且锁定在生成的机器代码中,您会看到它们被推入堆栈中): char* str = (char[]){“Hello World”}; *str = ‘B’; // A-Okay! 我正在使用clang-703.0.29编译。 这两个例子不应该生成完全相同的机器代码吗? 如果它是可修改的,复合文字真的是文字吗? 编辑:一个更短的例子是: “Hello World”[0] = ‘B’; // Bus Error! (char[]){“Hello World”}[0] = ‘B’; // Okay!

无符号整数递增会导致未定义的定义行为吗?

在64位读取32位无符号乘法后导致未定义的行为? 问题在StackOverflow上,我开始思考根据C99标准,对小型无符号类型的典型算术运算是否会导致未定义的行为。 例如,请使用以下代码: #include … unsigned char x = UCHAR_MAX; unsigned char y = x + 1; x变量初始化为unsigned char数据类型的最大幅度。 下一行是问题:值x + 1大于UCHAR_MAX ,不能存储在unsigned char变量y 。 我相信以下是实际发生的事情。 变量x首先被提升为数据类型int (第6.3.1.1/2节),然后x + 1被计算为数据类型int 。 假设存在INT_MAX和UCHAR_MAX相同的实现 – x + 1将导致有符号整数溢出。 这是否意味着递增变量x ,尽管是无符号整数类型,由于可能的有符号整数溢出会导致未定义的行为?

const数组const {}

所以你可以这样做: void foo(const int * const pIntArray, const unsigned int size); 这表示指针是只读的,它指向的整数是只读的。 你可以像这样访问函数内部: blah = pIntArray[0] 您还可以执行以下声明: void foo(const int intArray[], const unsigned int size); 它几乎是一样的,但你可以这样做: intArray = &intArray[1]; 我可以写: void foo(const int const intArray[], const unsigned int size); 那是对的吗?

UINT32_C和uint32_t之间的区别

据我所知, uint32_t中的后缀t表示名称,但我想知道UINT32_C中的C是什么 ,有什么区别?

没有强制转换的整数指针

当我调用一个需要指针的函数,并传入一个值时,我得到了这个警告,我喜欢这样。 但是当值恰好是字面值’0’时,我没有得到警告。 我认为这是因为C认为它是空指针,而不是值。 有没有办法仍然得到0字面的警告,因为我已经有一些错误因为它。

NaN生成函数的“char-sequence”参数是什么?

除了NAN宏之外,C99还有两种方法可以为浮点数生成NaN值,即nanf(const char *tagp)函数和strtof(“NAN(char-sequence)”) 。 这两种生成NaN的方法都采用可选的字符串参数(在nanf() * tagp,在strtof方法中为char-sequence)。 这个字符串参数到底是做什么的? 我还没有找到你如何使用它的具体例子。 来自cppreference.com我们有: 调用nan(“string”)等同于调用strtod(“NAN(string)”,(char **)NULL); 调用nan(“”)等同于调用strtod(“NAN()”,(char **)NULL); 调用nan(NULL)等效于调用strtod(“NAN”,(char **)NULL); 而nan(3)说: 这些函数返回一个安静的NaN的表示(由tagp确定)。 [snip]参数tagp以未指定的方式使用。 在IEEE 754系统上,有许多NaN表示,tagp选择一个。 这并没有真正告诉我我可以用于tagp字符串或为什么我想要使用它。 此标记字符串的有效选项中是否有列表,以及使用默认nanf(NULL)的原因是什么?

任何人都可以在下面的例子中解释C预处理器的行为吗?

我正在实现一个C宏预处理器(C99)…… 我对以下行为感到惊讶…. EX1: #define PASTE(x)X _ ## x #define EXPAND(x)PASTE(x) #define TABSIZE 1024 #define BUFSIZE TABSIZE PASTE(BUFSIZE) EXPAND(BUFSIZE) 扩展为: X_BUFFSIZE X_1024 EX2: #define EXPAND(s)TO_STRING(s) #define TO_STRING(s)#s #define四个4 TO_STRING(四) EXPAND(四) 扩展到: “四个一” “4” 我已经完成了C的“免费”标准,但我找不到以下内容…… 实际上预处理器执行了多少次传递? 它首先替换一个宏,然后替换其他宏等等 或者它是否存储并替换为#define s逐个遇到? 文件包含是先完成还是宏扩展?

所有结构标识符都自动向前声明

在回答警告:从链表数组的不兼容指针类型进行赋值时 ,我注意到任何用struct关键字识别的未声明标识符都被视为前向声明的标识符。 例如, 下面的程序编译得很好: /* Compile with “gcc -std=c99 -W -Wall -O2 -pedantic %” */ #include struct foo { struct bar *next; /* Linked list */ }; int main(void) { struct bar *a = 0; struct baz *b = 0; struct foo c = {0}; printf(“bar -> %p\n”, (void *)a); printf(“baz -> %p\n”, (void *)b); […]

什么ABI,如果有的话,限制 intmax_t的大小?

从1999版本开始,ISO C标准定义了一个标准头文件 ,它定义了typedef intmax_t和uintmax_t 。 它们分别指定“能够表示任何(有符号|无符号)整数类型的任何值的一个(有符号|无符号)整数类型”。 例如,如果典型地,最宽的有符号和无符号整数类型是long long int和unsigned long long int ,两者通常都是64位,那么intmax_t和uintmax_t可能在定义如下: typedef long long int intmax_t; typedef unsigned long long int uintmax_t; 有一组有限的预定义有符号和无符号整数类型,范围从signed , unsigned和plain char到signed和unsigned long long int 。 C99和C11还允许实现定义扩展的整数类型 ,这些类型不同于任何标准类型,并且具有实现定义的关键字的名称。 gcc和clang在某些但不是所有目标上都支持__int128和unsigned __int128类型。 这些行为类似于128位整数类型,但它们不被视为扩展整数类型 ,并且两个编译器的文档都声明它们不支持任何扩展整数类型。 由于这些不是整数类型,因为标准定义了术语,因此intmax_t和uintmax_t适用于64位类型,而不是128位类型。 这些都不违反C标准(实现不需要具有任何扩展的整数类型,并且只要它们不破坏任何严格符合的程序,它们就被允许具有任意扩展)。 但在我看来,将__int128和unsigned __int128视为扩展整数类型,并将intmax_t和uintmax_t视为128位类型是intmax_t uintmax_t 。 不这样做的基本原理是改变intmax_t和uintmax_t的大小将是“ABI不兼容的变化”。 Clang C ++状态页面在脚注(5)中说: 对于没有提供任何扩展整数类型的Clang等实现,不需要进行编译器更改。 __int128不被视为扩展整数类型,因为更改intmax_t将是ABI不兼容的更改。 (是的,这主要讨论C ++,但规则与C相同) 在gcc错误报告中 ,声称: sizeof(intmax_t)由各种LP64 […]