小编Dan*_*Dan的帖子

有符号整数溢出是否定义了未定义的行为或实现?

#include <limits.h>

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

我这个 UB 或实现定义?

链接说它的 UB

https://www.gnu.org/software/autoconf/manual/autoconf-2.63/html_node/Integer-Overflow-Basics

允许 C/C++ 中的有符号整数溢出

链接说它的实现定义

http://www.enseignement.polytechnique.fr/informatique/INF478/docs/Cpp/en/c/language/signed_and_unsigned_integers.html

转换规则说:

否则,新类型是有符号的,值不能在其中表示;要么结果是实现定义的,要么引发实现定义的信号。

我们不是将 a 转换max unsigned value为 asigned value吗?

我所看到的方式,gcc 只是截断了结果。

c undefined-behavior implementation-defined-behavior

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

访问结构中的数组会导致发出叮当声警告

struct test{
   char c_arr[1];
};

test array[1] = {{1}};

test get(int index){
 return array[index];
}

int main(){
  char* a =  get(0).c_arr;
  return 0;
}
Run Code Online (Sandbox Code Playgroud)

编译它g++没有警告但clang++打印以下内容:

warning: temporary whose address is used as value of local variable 'a' will be destroyed at the end of the full-expression
Run Code Online (Sandbox Code Playgroud)

这不正确吗?不get(0).c_arr返回指向全局数组的指针?

还是get(0)返回一个临时变量并且编译器错误地认为c_arr它只是它的一个实例,而不是全局变量?

编辑

为什么将此临时变量传递给函数可以在没有警告的情况下工作?

void call(char* in){}

int main(){
  call(get(0).c_arr);
  return 0;
}
Run Code Online (Sandbox Code Playgroud)

c++ temporary-objects

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

C++类中变量的多重定义

假设这两个 cpp 文件:

0.cc

#include <iostream>

class test{
 public:
 int num = 5;
};

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

1.cc

class test{
 public:
 int num = 6; // <-- note this has a different value.
};
Run Code Online (Sandbox Code Playgroud)

我们用g++ 0.cc 1.cc.

从 C++11 开始,在类中初始化成员变量是有效的。我的问题是它如何编译 whiteout 链接器错误?这是未定义的行为吗?因为我们正在打破一个定义规则。如果没有使用类,这将在编译时产生链接错误。

我知道在一个类中定义一个函数会使其内联,因此可以在不同的文件中包含多个函数,但不确定多个变量如何?

c++

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

`const` 关键字是用于函数声明、定义还是两者兼而有之?

void test(int& in);
void test(const int& in){

}

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

上面没有编译链接错误:undefined reference to `test(int&)'

我对此有3个问题:

1- 为什么我们会收到链接错误?是因为添加const到定义中使其成为完全不同的功能吗?为什么在不使用引用时它会起作用,即这可以正常工作:

void test(int in);
void test(const int in){}
..
 int a = 5; 
 test(a);
..
Run Code Online (Sandbox Code Playgroud)

2- 是否const进入函数声明、定义或两者?如果使用引用,行为似乎有所不同。

3-const参数上的关键字是否说“传递给我的参数应该是调用者中的常量”“此参数在此函数范围内被视为常量,无论它在调用者中是否为常量”。我确定是后者,但想确认一下。

c++

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

读取与在联合中写入的成员不同的成员是否是未定义的行为?

union test{
  char a; // 1 byte
  int b;  // 4 bytes
};

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

这个链接说:https : //en.cppreference.com/w/cpp/language/union

从最近未写入的联合成员中读取是未定义的行为。

据此,我上面的示例代码有UB吗?如果是这样,那么联盟的意义何在?我认为重点在于从相同的内存位置读取/写入不同的值类型。

如果我需要访问该most recently written值,那么我将只使用常规变量而不是联合。

c++

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

在 C++ 中通过引用传递整个数组的不同方法

#include <iostream>

template <class T>
void call_1(T& in){
  printf("%d\n", sizeof(in));  // 12
}

template <int N>
void call_2(int (&in)[N]){
   printf("%d\n", sizeof(in)); // 12
}

int main(){
  int a[] = {1,2,3};
  call_1(a);
  call_2(a); 
  return 0;
}
Run Code Online (Sandbox Code Playgroud)

根据上面的代码片段,我有几个问题:

1-是call_1call_2都有效的方式来传递通过引用整个阵列?

2- 为什么T&需要在call_1. 如果&省略,则传递指向数组第一个元素的指针。为什么不T&传递对数组第一个元素的引用,而是引用整个数组?

3-为什么我不能写template <T N>call_2一个避免硬编码int?这不是有效的语法吗?

c++

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

什么是加宽整数运算?

让我们检查AddMultiply作为例子。哪一种可以归类为加宽

假设输入是2 的补码中的有符号字符(即长度为 8 位),除非另有声明。

正数加法

1+2 = 3
Run Code Online (Sandbox Code Playgroud)

这个操作似乎没有扩大。1、2 和 3 都适合一个字符。

但是,250 + 6溢出无符号字符。那么这是在扩大吗?

同样可以用有符号类型完成,将有符号125 + 5字符溢出到符号位中。这是在扩大吗?

负数加法

-2-3 = -5
Run Code Online (Sandbox Code Playgroud)

这会使二进制字符溢出 1 位:

   1 1 1 1 1 1 1 0
+  1 1 1 1 1 1 0 1
------------------ 
 1 1 1 1 1 1 0 1 1 
Run Code Online (Sandbox Code Playgroud)

溢出通常会被丢弃,但是,这是否被视为扩大操作?

正数乘法

1 * 2 = 2
Run Code Online (Sandbox Code Playgroud)

即使结果仍然适合原始数据类型,所有乘法是否都在扩大?

上面的例子2仍然适合一个 8 位字符,但是,如果我用二进制手工进行数学运算,额外的0s会附加到结果的左侧,结果被丢弃。 …

assembly cpu-architecture twos-complement integer-arithmetic

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

翻译单元中具有不同定义的相同结构

0.c

#include <stdio.h>

struct test{
 int a;
};

struct test get(int in);

int main(){
 struct test t = get(1234);
 printf("%d\n",t.a);

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

1.c

struct test{
 char a;    // Note this is char instead of int.
};

struct test get(int in){
  struct test t = {in};
  return t;
}
Run Code Online (Sandbox Code Playgroud)

struct test有两种不同的定义。一个 with int,另一个 withchar作为其数据类型。

这是未定义的行为吗?C 没有one dentition rule像 C++ 那样的官方语言,这篇文章说多个定义可以吗?不同的翻译单元是否可以定义同名的结构体?

c

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

在 C++ 中将对象转换为不相关对象的正确方法是什么

#include <iostream>

class c1{
};

class c2{
};

int main(){
 c1 a;
 c2 b;
 //b = static_cast<c2>(a);   <-- will not compile
 
b = *reinterpret_cast<c2*>(&a);
  
 return 0;
}
Run Code Online (Sandbox Code Playgroud)

b = static_cast<c2>(a); 不会编译出现此错误:

no matching conversion for static_cast from 'c1' to 'c2'
Run Code Online (Sandbox Code Playgroud)

使用reinterpret_cast和做 abit cast是实现这一目标的唯一方法吗?

c++

0
推荐指数
1
解决办法
87
查看次数

将 int64_t 值与另一个 uint32_t 值进行比较

int main(){
 int64_t a = -1;
 uint32_t b = -1;

 bool c = a > b;
 std:: cout << c << std::endl;
 
 return 0;
}
Run Code Online (Sandbox Code Playgroud)

我的理解是b哪个较小的类型将转换为较大的类型a(unit32 到 int64):

int 与 long 及其他比较

然后a将有符号值转换为无符号值:

有符号/无符号比较

本质上我们的比较将变成:

18446744073709551615 > 4294967295
Run Code Online (Sandbox Code Playgroud)

但我的c结果是false。我在这里缺少什么?

c++

0
推荐指数
1
解决办法
1498
查看次数

数组声明是否意味着连续的内存分配?

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

在这个片段中char a[5];,没有任何初始化的数组声明是否保证分配 5 个字节的连续内存?

或者因为稍后只有 1 个元素被初始化,编译器可以自由地使用该 1 个元素的寄存器?

我假设读取此数组旁边的任何其他索引0都是未定义的行为。

c

0
推荐指数
1
解决办法
63
查看次数

数组是否保证在虚拟内存中是连续的?

int main() { 
 char a[3] = {1,2,3};
 return sizeof(a);
}
Run Code Online (Sandbox Code Playgroud)

a保证在虚拟内存中连续字节?我知道它在物理内存中可能不是连续的,因为映射是由 MMU 在幕后完成的。

如果编译器注意到我没有获取任何元素的地址,那么是否可以将它们放在内存中的非连续地址上,甚至将它们放在寄存器中?

让我们假设优化器不会在我的示例中完全摆脱它。

c

0
推荐指数
1
解决办法
90
查看次数