标签: c99

将受限指针分配给另一个指针,并使用第二个指针修改值是否合法?

以下方法是否尊重“限制”合同?

void fun(int* restrict foo) {
     int* bar = foo + 32;
     for (int i = 0; i < 32; ++i)
         *bar = 0;
}
Run Code Online (Sandbox Code Playgroud)

我的猜测是否定的,但我需要澄清一下。

c c99 restrict-qualifier

4
推荐指数
1
解决办法
640
查看次数

带和不带 -std=c99 的代码会产生不同的结果(UMAC AE 实现)

长话短说——我使用 Ted Krovetz 的实现来计算UMACUMAC AE加密 ( http://www.fastcrypto.org/ )。

当我用 编译我的代码(和/或中的测试umac.c)时-std=c99,计算出的结果UMAC与预期完全不同(并且是错误的)。当我删除这个选项时,一切都像魅力一样。

有什么想法可能导致这种情况吗?我可以做什么来检查发生了什么以及什么产生了不同的结果?


$ gcc --version
gcc (Ubuntu 4.8.2-19ubuntu1) 4.8.2

$ uname -a
xxx 3.13.0-43-generic #72-Ubuntu SMP .. x86_64 x86_64 x86_64 GNU/Linux
Run Code Online (Sandbox Code Playgroud)

我不使用任何其他选项 - 只是使用和不使用-std=c99.


再说几句话:

我会尝试联系 Ted Krovetz 并向他询问这个问题(可能是一些错误或其他问题),但这不是重点。这个问题有点笼统,这个具体问题可以看作是一个例子。

我跑了valgrind——没什么特别的。添加-Wall并且-Wextra-什么也没有了。听起来像UB,但valgrind没有抱怨任何事情。

这种情况非常有趣,花了我很多天和头痛才明白,问题不在我的代码中(我使用这个实现来实现复杂的协议),而是在算法中,尤其是在这个选项中。所以我决定征求意见。

在 C 和 C++ 中都有效的代码在用每种语言编译时会产生不同的行为吗?根本不相关,因为我们在这里谈论的是同一种语言。
这种没有“-std=c99”的巨大 fprintf 速度差异很接近,但还不够。


编辑

这是我的测试结果和我所做的(源/标题刚刚下载,我没有更改任何内容): …

c gcc c99 compiler-options

4
推荐指数
1
解决办法
353
查看次数

在C中流声明中不能有标签?

所以这在C99:

label:
  int ret = function(of, stuff);
Run Code Online (Sandbox Code Playgroud)

给出了一个编译时错误,而这个:

label:
  ;
  int ret = function(of, stuff);
Run Code Online (Sandbox Code Playgroud)

工作得很好.

这是编译器错误吗?或者这是C标准定义中的错误?或者,如果这是C99标准的一部分,也许有人会捍卫C标准,声称这是完全合理的?

c standards goto c99

4
推荐指数
1
解决办法
94
查看次数

union是否支持灵活的阵列成员?

我在联合中声明了一个灵活的数组成员,如下所示:

#include  <stdio.h>

union ut
{
    int i;
    int a[]; // flexible array member
};

int main(void)
{
    union ut s;
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

和编译器给出一个错误:

source_file.c:8:9: error: flexible array member in union
     int a[];
Run Code Online (Sandbox Code Playgroud)

但是,声明的数组大小如下:

union ut
{
    int i;
    int a[0]; // Zero length array
};
Run Code Online (Sandbox Code Playgroud)

它工作正常.

为什么零长度阵列工作精细?

c c99 unions flexible-array-member

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

在 c99 中初始化布尔数组的方法

在 C99 中初始化布尔数组的最佳方法是什么?

也许我可以用这个,我想。

bool f[5] = {false,};
Run Code Online (Sandbox Code Playgroud)

这真的好吗?

如果有更好的方法,请告诉我。

c boolean c99

4
推荐指数
1
解决办法
5234
查看次数

嵌套宏调用

尝试嵌套宏调用,如下所示:

#include <stdint.h>

#define INT
#define LONG

#define AS(t) AS_##t
#define AS_INT as_int
#define AS_LONG as_long

#define LET(v, t) v. AS(t)

typedef union
{
    int32_t as_int;
    int64_t as_long;
} mytype_t;

int main()
{
    mytype_t s;

    s.AS(INT) = 10;    /* This is OK */

    LET(s, INT) = 10;  /* This makes error */

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

它产生错误:

main.c:xx:yy: error: ‘mytype_t {aka union <anonymous>}’ has no member named ‘AS_’
 #define LET(v, t) v. AS(t)
                    ^
main.c:zz:ww: note: in expansion of macro ‘LET’ …
Run Code Online (Sandbox Code Playgroud)

c macros c99 c-preprocessor

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

C Keil 编译器使用 malloc 作为局部变量,为什么?

我在我想声明一个数组的函数中的代码中的某个地方遇到了问题,但它失败了。经过一些调试后,我发现它在反汇编窗口中使用了 malloc,所以我增加了堆大小并且它工作正常!

所以我的问题是为什么 keil 使用堆作为局部变量?

这是变量声明代码:

uint8_t result[data->capacityBytes];
memset(result, 0, sizeof(result));
Run Code Online (Sandbox Code Playgroud)

我添加了标志 C99

c malloc heap-memory c99 keil

4
推荐指数
1
解决办法
225
查看次数

为什么 const int x = 5; 不是C中的常量表达式吗?

本以为C不会再给我带来惊喜了,但这却让我大吃一惊。

    const int NUM_FOO = 5;
    ....

    int foo[NUM_FOO];
==>error C2057: expected constant expression
Run Code Online (Sandbox Code Playgroud)

我的 C++ 经验让我在内部#define尽可能地反对。所以这真是一个惊喜。VS2019,使用/TC编译。我认为 C99 无论如何都允许可变大小的数组。

  1. 任何人都可以解释为什么会发生拒绝,因为编译器在编译时肯定知道数组的大小?

  2. C99不是允许可变大小数组吗?

c constants c99 variable-length-array visual-studio-2019

4
推荐指数
1
解决办法
2636
查看次数

在函数开头声明变量有什么好处吗?

我知道 C99 之前的编译器需要在函数开头声明变量来计算堆栈大小。然后要求就被取消了。如今,除了向后兼容性之外,仍然坚持该方案是否有任何好处,或者也许仅在需要变量时以及在更需要变量的地方才声明变量?(例如,在 if 语句中,其中一个分支需要变量,但第二个分支不需要)

c c99

4
推荐指数
1
解决办法
1220
查看次数

C 联合类型双关数组

鉴于以下代码,我有一些与类型双关相关的问题。我看不出这没有违反严格的别名规则,但我无法指出具体的违规行为。我最好的猜测是,将联合成员传递到函数中违反了严格的别名。

以下代码位于Compiler Explorer上。

#include <stdint.h>

union my_type
{
    uint8_t m8[8];
    uint16_t m16[4];
    uint32_t m32[2];
    uint64_t m64;
};

int func(uint16_t *x, uint32_t *y)
{
    return *y += *x;
}

int main(int argc, char *argv[])
{
    union my_type mine = {.m64 = 1234567890};
    return func(mine.m16, mine.m32);
}
Run Code Online (Sandbox Code Playgroud)

我的观察:

  • 假设参数func不互相别名,func则不违反严格别名。
  • 在 C 语言中,允许使用unionfor 类型双关。
  • 通过m16m32进入func必须违反某些内容。

我的问题:

  • 像这样的数组类型双关有效吗?
  • 我将指针传递给 到底违反了什么func
  • 在这个例子中我还遗漏了哪些其他问题?

c c99 c11

4
推荐指数
1
解决办法
371
查看次数