小编Dan*_*Dan的帖子

在 C++ 中,用自身初始化全局变量是否具有未定义的行为?

int i = i;

int main() { 
 int a = a;
 return 0;
} 
Run Code Online (Sandbox Code Playgroud)

int a = a肯定有未定义的行为 (UB),关于它的更多细节在 读取未初始化的值总是未定义的行为吗?或者有例外吗?.

但是呢int i = i?在 C++ 中,我们可以为全局变量分配非常量值。i在遇到声明之前声明并零初始化(因为它具有文件范围)。在这种情况下,我们将0在定义的后面分配给它。可以说这没有 UB 吗?

c++ undefined-behavior language-lawyer

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

char 数组是否保证以 null 终止?

#include <stdio.h>

int main() {
    char a = 5;
    char b[2] = "hi"; // No explicit room for `\0`.
    char c = 6;

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

每当我们编写一个用双引号括起来的字符串时,C 都会自动为我们创建一个字符数组,其中包含该字符串,并以 \0 字符结尾 http://www.eskimo.com/~scs/cclass/notes/sx8。 html

在上面的示例中,b只有 2 个字符的空间,因此空终止字符没有位置可放置,但编译器正在重新组织内存存储指令,以便将ac存储b在内存中,以便为 a 腾出\0空间数组的末尾。

这是预期的还是我遇到了未定义的行为?

c string-literals array-initialization

55
推荐指数
3
解决办法
1万
查看次数

在 C 中的宏之外使用反斜杠换行符

int main(){\
 int a = 5;\
 return a;\
}
Run Code Online (Sandbox Code Playgroud)

以上编译正常。我假设 C 预处理器在编译之前删除了反斜杠?

gcc -E 的输出

int main(){
 int a = 5;
 return a;}
Run Code Online (Sandbox Code Playgroud)

似乎并非所有\n(新行)字符都像使用宏一样被删除,它只是主要删除了反斜杠。

我已经在多行宏中看到过这种用法,例如:

#define TEST(in)\
 int a = in;    \
 int b = 6;

int main(){
 TEST(5)
 return 0;
}
Run Code Online (Sandbox Code Playgroud)

gcc -E 的输出:

int main(){
 int a = 5; int b = 6;
 return 0;
}
Run Code Online (Sandbox Code Playgroud)

预处理将删除反斜杠以及\n上面示例中的字符,但为什么它没有删除我第一个示例中的所有换行符?

c c-preprocessor

6
推荐指数
1
解决办法
124
查看次数

添加两个字符并将结果分配给 C 中的 int

int main(){

 char a = -5;
 char b = -6;
 int c = a+b;
 return 0;
}
Run Code Online (Sandbox Code Playgroud)

我在不同的体系结构中得到了不同的结果,使用gcc.

x86变量c进行了正确的符号扩展,我得到-11.

在其他一些架构c上没有符号扩展,你得到a+b位转换为 an的结果,int我得到501.

这是未定义的行为吗?

c

5
推荐指数
1
解决办法
52
查看次数

读取未初始化的值总是未定义的行为吗?或者有例外吗?

在读取值时,未定义行为(UB) 的一个明显示例是:

int a;
printf("%d\n", a);
Run Code Online (Sandbox Code Playgroud)

下面的例子呢?

int i = i;     // `i` is not initialized when we are reading it by assigning it to itself.
int x; x = x;  // Is this the same as above?
int y; int z = y;
Run Code Online (Sandbox Code Playgroud)

上面的三个例子都是 UB,还是有例外?

c

5
推荐指数
1
解决办法
252
查看次数

在 C 中使用空终止字符作为空指针

#include <stdio.h>

int main(){
 int *p = '\0';
 if (p == NULL){
   // this block will get executed.
 }
 return 0;
}
Run Code Online (Sandbox Code Playgroud)

我已经读过0NULL并且\0都等于0C 中的整数常量。那么上面的代码在设置和检查 NULL 指针时在技术上是否正确?我想它仍然需要避免,因为\0它主要用于终止字符串并且它在这里的用法令人困惑?

c

5
推荐指数
0
解决办法
94
查看次数

引用匿名结构本身

typedef struct {
    //
} list;

Run Code Online (Sandbox Code Playgroud)

对比

typedef struct list{
    //
} list;

Run Code Online (Sandbox Code Playgroud)

我在另一篇文章中读到过(例如使用匿名结构与带有 typedef 的命名结构),其中说这两个几乎是等效的,并且需要后者的唯一时间是在引用结构本身时。

但是,以下内容可以用 clang 和 gcc 编译得很好:

#include <stdio.h>

typedef struct {
    struct list *next;
} list;

int main(){
 list l;
 return  0;
}
Run Code Online (Sandbox Code Playgroud)

上面我有一个匿名结构引用它自己。这是如何编译的?

c struct typedef declaration forward-declaration

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

为什么在 C++ 中允许重新声明模板成员函数?

class test{
 public:
 int call();
};

int test::call();

int main(){return 0;}
Run Code Online (Sandbox Code Playgroud)

上面的不会编译,出现这个错误:

error: declaration of 'int test::call()' outside of class is not definition 
Run Code Online (Sandbox Code Playgroud)

但是,如果这样使用模板,则允许使用相同的代码:

class test{
 public:
 template<class T>
 int call();
};

template int test::call<int>(); // what's the point of this line?

template <class T>
int test::call(){
  T in = 5;
  return in;
}

int main(){
 test t;
 
 return 0;
}
Run Code Online (Sandbox Code Playgroud)

我有两个问题:

1-重新声明有什么意义?我在其他项目中看到过类似的代码。

2- 为什么它可以编译而我的第一个代码片段却不能?

c++

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

将无符号值分配给有符号字符

关于 C 中类型转换的简单问题,假设这行代码:

signed char a = 133;
Run Code Online (Sandbox Code Playgroud)

由于有符号字符的最大值是128,上面的代码是否具有implementation defined根据第三条转换规则的行为?

如果值不能用新类型表示并且它不是无符号的,那么新类型是有符号的并且值不能在其中表示;要么结果是实现定义的,要么引发实现定义的信号。

c language-lawyer

3
推荐指数
1
解决办法
136
查看次数

转换有符号整数与短整数时符号扩展不一致

int main(){
  signed int a = 0b00000000001111111111111111111111; 
  signed int b = (a << 10) >> 10;
  // b is: 0b11111111111111111111111111111111

  signed short c = 0b0000000000111111; 
  signed short d = (c << 10) >> 10;
  // d is: 0b111111

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

假设int是 32 位和short16 位,

为什么会b得到符号扩展但d没有得到符号扩展?我已经在 x64 上用 gdb 测试过这个,用 gcc 编译。

为了获得short符号扩展,我不得不使用两个单独的变量,如下所示:

  signed short f = c << 10;
  signed short g = f >> 10;
  // g is: …
Run Code Online (Sandbox Code Playgroud)

c

3
推荐指数
1
解决办法
69
查看次数