标签: c99

作业评估顺序(我找到了第一个编译器错误吗?)

这段代码有一个有趣的bug:

some_struct struct_array1[10] = {0};
some_struct struct_array2[10] = {0}
int i;

for (i = 0; 
     i < sizeof(struct_array1) / sizeof(struct_array1[0]); 
     struct_array1[i].value = struct_array2[i++].value = 1)
    ;
Run Code Online (Sandbox Code Playgroud)

对于大多数编译器,上面的代码导致将相应数组中所有结构的"value"字段设置为1.但是,对于一个特定的编译器(让我们称之为xcc),struct_array1中的结构未正确初始化.对于所有结构,"value"字段设置为0,这让我感到惊讶.

以下代码段在所有编译器上按预期工作:

for (i = 0; 
     i < sizeof(struct_array1) / sizeof(struct_array1[0]); 
     i++)
{
    struct_array1[i].value = struct_array2[i].value = 1;
}
Run Code Online (Sandbox Code Playgroud)

现在,我完全离开这里,还是有问题的编译器"xcc"只是显示错误?

我在第一个代码片段中找不到任何显示特定于实现的行为的内容; 根据我的理解,后缀增量应该优先于赋值,并且应该从右到左评估赋值.第一个代码片段应该没什么奇怪的,除了它有点不可读.

c c99 undefined-behavior

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

C99:数组或堆分配的缓冲区是否会以UINTPTR_MAX结束?

我可以假设以下不变量吗?

void foo(char *buf, size_t len) {
  // "buf" points to either an array or memory allocated with malloc().
  assert((uintptr_t)(buf + len) < UINTPTR_MAX);
}
Run Code Online (Sandbox Code Playgroud)

在我正在编写的解析器中,我想使用指针标记某些偏移:例如,我可能有char *end_of_submessage,end_of_submessage相对于我当前的缓冲区.但是如果子消息没有在当前缓冲区内结束,我想使用一个大于当前缓冲区中任何偏移量的值.所以我会这样做:

void parse(char *buf, size_t len, uintptr_t end_of_submessage) {
  // Some parsing that might increment "buf"
  // ...

  // If end_of_submessage == UINTPTR_MAX, processing will not be
  // triggered even if we have processed our entire current buffer.
  if ((uintptr_t)buf >= end_of_submessage)
    process_submsg_end();
}
Run Code Online (Sandbox Code Playgroud)

但是如果malloc()返回内存ptr + len == UINTPTR_MAX …

c pointers c99 intptr

2
推荐指数
1
解决办法
185
查看次数

使用ISO C99 printf("%Nd")的前导零默认行为?

我刚刚在C99 ISO标准7.19.6.1 The fprintf function第6小节中发现了以下内容,详细说明了转换标志,特别是0标志:

0: d,i,o,u,x,X,a,A,e,E,f,F,g和G转换,前导零(跟随符号或基数的任何指示)用于填充场宽度而不是执行空间填充,除非转换无穷大或NaN.

到目前为止,我知道以下几行将产生显示的输出:

printf ("%5d\n", 7);   // produces "    7"
printf ("%05d\n",7);   // produces "00007"
Run Code Online (Sandbox Code Playgroud)

但是,在第8小节详细说明了转换修饰符,我看到:

d,i: int参数在样式[ - ] dddd中转换为带符号的十进制数.精度指定要显示的最小位数; 如果转换的值可以用更少的数字表示,则使用前导零进行扩展.

显然不是这种情况,因为默认行为是填充空格而不是零.或者我在这里误读了什么?

c printf iso c99

2
推荐指数
1
解决办法
285
查看次数

GCC缓存循环变量吗?

当我有一个像这样的循环:

for (int i = 0; i < SlowVariable; i++)
{
   //
}
Run Code Online (Sandbox Code Playgroud)

我知道在VB6中,SlowVariable每次迭代循环都会访问它,使得以下内容更有效:

int cnt = SlowVariable;

for (int i = 0; i < cnt; i++)
{
   //
}
Run Code Online (Sandbox Code Playgroud)

我是否需要在GCC中进行相同的优化?或者它只评估SlowVariable一次?

c optimization performance gcc c99

2
推荐指数
1
解决办法
411
查看次数

如何处理clang编译器的警告?

我希望我的程序能够在没有警告的情况下使用clang进行编译.该功能似乎在编译时有效但为什么?我该如何处理警告?

$ clang cpu-disk-info.c
cpu-disk-info.c:108:17: warning: implicit declaration of function 'read' is
      invalid in C99 [-Wimplicit-function-declaration]
    while ((n = read(0, buf, betterSIZE)) > 0)
                ^
cpu-disk-info.c:109:5: warning: implicit declaration of function 'write' is
      invalid in C99 [-Wimplicit-function-declaration]
    write(1, buf, n);
    ^
Run Code Online (Sandbox Code Playgroud)

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

#define SIZE 1024
#define betterSIZE 4*SIZE /* read a better size at a time */

int main(int argc, char **argv)
{

    /* copy(); */

    /* make the names known */

    void info(char …
Run Code Online (Sandbox Code Playgroud)

c c99 clang

2
推荐指数
1
解决办法
8564
查看次数

GCC编译器对C/C++标准保持多少?

例如,具有C99标准的C编程语言支持十六进制浮点文字,但C++与C++ 03标准不支持.

我对它进行了测试,GCC在C++ 03模式下识别了十六进制浮动文字(-std = c ++ 03),但根据C++标准,它不应该.我知道,这不是一个悲剧,我只是对这个问题感兴趣..

GCC编制器是否符合标准?你能推荐我一个符合标准"完美"的C/C++编译器吗?

gcc c99 c++03

2
推荐指数
1
解决办法
114
查看次数

初始化变量并在声明后立即为其赋值是否有区别?

假设一个纯粹的非优化编译器,在初始化变量并在声明后为其赋值时,机器代码是否存在差异?

初始化方法:

int x = 2;
Run Code Online (Sandbox Code Playgroud)

作业方式:

int x;
x = 2;
Run Code Online (Sandbox Code Playgroud)

我使用GCC输出为这两种不同方法生成的程序集,并且两者都产生了一条机器指令:

movl    $2, 12(%esp)
Run Code Online (Sandbox Code Playgroud)

该指令只是将x变量保存的内存设置为值2.GCC可能会对此进行优化,因为它可以识别操作的最终结果; 但我认为这是解释这两个版本的唯一方法.我的理由是两个版本都做同样的事情:将内存的一部分设置为特定值.

那么,如果生成的机器代码相同,那么为什么通常会在术语" 初始化 "和" 赋值 " 之间进行区分?

术语" 初始化 " 是否纯粹用于区分具有特定值的变量,这些变量具有在内存中留下任何垃圾值的那些(非初始化)变量?

c assembly initialization c99 variable-assignment

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

C99:"int const*ptr"是什么意思?

我正在查看C99规范(N1256.pdf),其中说(第11506页):

const int *ptr_to_constant;
int *const constant_ptr;
Run Code Online (Sandbox Code Playgroud)

"ptr_to_constant指向的任何对象的内容不应该通过该指针修改,但是ptr_to_constant本身可以更改为指向另一个对象.同样,constant_ptr指向的int的内容可能会被修改,但是constant_ptr本身应该总是指向同一地点." (6.7.5.1指针声明符)

从我之前读到的内容来看,以下两个陈述产生了相同的行为.

int *const constant_ptr; /* This form is mentioned in the standard */
int const *constant_ptr; /* This form is NOT mentioned in the standard */
Run Code Online (Sandbox Code Playgroud)

我想知道第二种形式是正确的还是只是一种延伸.

在此先感谢,-S

c pointers constants c99

2
推荐指数
1
解决办法
3640
查看次数

C99指定的初始化程序或CGMake宏?

C99指定初始化器或各种CGSizeMake,CZRectMake等宏是否更像现代Objective-C中的惯例?

它几乎看起来像个人风格偏好,但我看到的C99风格的一个优点是价值的意图是清晰明确的.

CGRect rect = CGRectMake(x, y, width, height) 
Run Code Online (Sandbox Code Playgroud)

如果你混淆了价值的顺序,会给你带来心痛,如:

CGRect rect = (CGRect){.origin.x = x, .origin.y = y, .size.width = width, .size.height = height};
Run Code Online (Sandbox Code Playgroud)

毫无疑问,高度正在获得你给予它的价值.人们继续使用现有宏的原因是什么?

"可可编码公约"的文档中没有任何关于此的内容和我遇到的风格指南之一,它是GitHub风格指南:https://github.com/github/objective-c-conventions

objective-c c99

2
推荐指数
1
解决办法
228
查看次数

`pixel(*copy)[rows] = malloc(cols*sizeof(*copy))需要多少次调用free()?

我已经看到了在C99中使用以下表达式分配2D数组的各种建议:

int (*array)[cols] = malloc(rows * sizeof *array);
Run Code Online (Sandbox Code Playgroud)

我想知道三件事:

  1. 整个结构是否在堆上分配?或者这实际上是一堆指针(在堆栈上)指向堆上的数组..?

  2. 分配的内存是否完全连续?

  3. 是否只需要一次调用free(array)来释放整个2D结构?我在某个地方读过这个 - 不记得在哪里 - 它似乎对我有用,但我想明白为什么.

c arrays malloc free c99

2
推荐指数
1
解决办法
131
查看次数