中兴豫建设管理有限公司网站,039 织梦云idc网站源码,房地产网站策划书,wordpress启用GZIP压缩文章目录 一、未定义行为Undefined Behavior(UB)1.返回一个未初始化的局部变量的值2.数组越界访问3.有符号数的常量表达式溢出4.new与delete5.vector6.空指针解引用 参考 一、未定义行为Undefined Behavior(UB)
在C中#xff0c;未定义行为#xff08;Undefined Behavior中未定义行为Undefined Behavior指的是程序的行为没有定义、不可预测或不符合C标准的情况。当程序中存在未定义行为时编译器和运行时环境不会对其进行任何保证可能会导致程序产生意外的结果。
以下是一些常见的导致未定义行为的情况 访问未初始化的变量如果使用未初始化的变量其值是不确定的可能包含任意的垃圾值。 数组越界访问当访问数组时如果超出了数组的有效索引范围将导致未定义行为。 空指针解引用当将空指针用作指针解引用即访问其指向的内存区域时将导致未定义行为。 除以零在C中除以零是一种未定义行为可能导致程序崩溃或产生无效的结果。 使用已释放的内存如果使用已释放的内存或者使用指向已释放内存的指针将导致未定义行为。 栈溢出当递归调用或者使用过多的局部变量导致栈空间耗尽时将导致未定义行为。 多个线程之间的竞争条件如果多个线程同时访问并修改共享数据而没有适当的同步机制可能会导致未定义行为。 编译器使用x86_64 gcc13.2 C版本-stdc20 1.返回一个未初始化的局部变量的值
UB写法
#include cstdioint func()
{int i;return i;
}int main()
{int i func();printf(%d\n,i);return 0;
}编译及运行结果
Program returned: 0
Program stdout
0使用编译期constexpr检测UB
#include cstdioconstexpr int func()
{int i;return i;
}int main()
{constexpr int i func();printf(%d\n,i);return 0;
}编译及运行结果
source: In function constexpr int func():
source:6:9: error: uninitialized variable i in constexpr function6 | int i;| ^
source: In function int main():
source:12:27: error: constexpr int func() called in a constant expression12 | constexpr int i func();| ~~~~^~通过constexpr 进行UB检测
#include cstdioconstexpr int func(int i)
{if (i 0)return 0;}int main()
{constexpr int _1 func(1);constexpr int _2 func(-1);return 0;
}编译及运行
Could not execute the program
Compiler returned: 1
Compiler stderr
source: In function int main():
source:14:28: in constexpr expansion of func(-1)
source:14:31: error: constexpr call flows off the end of the function14 | constexpr int _2 func(-1);|编译期使用constexpr 检测UB 写法关于移位的例子
int类型的数据4Bytes最多只能移动31bit
#include cstdioconstexpr int func(int i)
{return 1 i;
}int main()
{constexpr int _1 func(32);constexpr int _2 func(-1);printf(%d\n,_1);return 0;
}编译及运行 source: In function int main():
source:11:28: in constexpr expansion of func(32)
source:6:14: error: right operand of shift expression (1 32) is greater than or equal to the precision 32 of the left operand [-fpermissive]6 | return 1 i;| ~~^~~~
source:12:28: in constexpr expansion of func(-1)
source:6:14: error: right operand of shift expression (1 -1) is negative [-fpermissive]2.数组越界访问
编译期通过constexpr检测UB写法
#include cstdioconstexpr int func(int i)
{int a[32]{};return a[i];
}int main()
{constexpr int _1 func(0);constexpr int _2 func(32);printf(%d\n,_1);return 0;
}编译及运行
source: In function int main():
source:14:28: in constexpr expansion of func(32)
source:8:15: error: array subscript value 32 is outside the bounds of array a of type int [32]8 | return a[i];| ~~~^
source:6:9: note: declared here6 | int a[32]{};| ^使用编译期constexpr检测UB
#include cstdio
#include cmath
#include array
#include algorithmconstexpr int func(int i)
{int a[32]{};// std::fill(a, a2,0);//编译期检测直接访问数组外的数据并不会出错,但是在return中使用就会出错int* b a32;*b;return *std::end(a);
}int main()
{constexpr int _1 func(0);constexpr int _2 func(32);printf(%d\n,_1);return 0;
}编译以及运行 source: In function int main():
source:20:28: in constexpr expansion of func(0)
source:20:30: error: array subscript value 32 is outside the bounds of array type int [32]20 | constexpr int _1 func(0);| ^
source:21:28: in constexpr expansion of func(32)
source:21:31: error: array subscript value 32 is outside the bounds of array type int [32]21 | constexpr int _2 func(32);编译期使用constexpr检测UB行为
#include cstdio
#include cmath
#include array
#include algorithmconstexpr int func(int i)
{int a[32]{};return *(char*)a;
}int main()
{constexpr int _1 func(0);constexpr int _2 func(32);printf(%d\n,_1);return 0;
}编译及运行
如果不使用constexpr就无法检测出这个指针强潜在的UB行为C语言可以跨平台如果Host主机是大端的而不是小端的那么强转后的地址一定是数据的低位吗 source: In function int main():
source:16:28: in constexpr expansion of func(0)
source:11:13: error: a reinterpret_cast is not a constant expression11 | return *(char*)a;| ^~~~~~~~
source:17:28: in constexpr expansion of func(32)
source:11:13: error: a reinterpret_cast is not a constant expression3.有符号数的常量表达式溢出
编译期使用constexpr检测UB行为
#include cstdio
#include cmath
#include array
#include algorithm// #define constexprconstexpr int func(int i)
{ return i 1;
}int main()
{constexpr int _1 func(2147483647);constexpr int _2 func(-2147483648);printf(%d\n,_1);return 0;
}编译及运行 source: In function int main():
source:15:28: in constexpr expansion of func(2147483647)
source:15:39: error: overflow in constant expression [-fpermissive]15 | constexpr int _1 func(2147483647);| ^4.new与delete
使用constexpr检测UB行为
#include cstdio
#include cmath
#include array
#include algorithm// #define constexprconstexpr int func(int n)
{ int *pnew int[n];delete p;return 0;
}int main()
{// constexpr int _1 func(0);constexpr int _2 func(1);printf(%d\n,_2);return 0;
}编译及运行
source: In function int main():
source:19:28: in constexpr expansion of func(1)
source:11:12: error: non-array deallocation of object allocated with array allocation11 | delete p;| ^
source:10:21: note: allocation performed here10 | int *pnew int[n];| ^
使用constexpr检测UB行为
#include cstdio
#include cmath
#include array
#include algorithm// #define constexprconstexpr int func(int n)
{ int *pnew int[n]{};delete[] p;return p[0];
}int main()
{// constexpr int _1 func(0);constexpr int _2 func(1);printf(%d\n,_2);return 0;
}编译及运行 source: In function int main():
source:19:28: in constexpr expansion of func(1)
source:19:30: error: use of allocated storage after deallocation in a constant expression19 | constexpr int _2 func(1);| ^
source:10:23: note: allocated here10 | int *pnew int[n]{};| ^使用constexpr检测UB行为
#include cstdio
#include cmath
#include array
#include algorithm// #define constexprconstexpr int func(int n)
{ int *pnew int[n]{};// delete[] p;return p[0];
}int main()
{// constexpr int _1 func(0);constexpr int _2 func(1);printf(%d\n,_2);return 0;
}编译以及运行
source: In function int main():
source:10:23: error: func(1) is not a constant expression because allocated storage has not been deallocated10 | int *pnew int[n]{};| ^使用智能指针在consexpr中自动析构 #include cstdio
#include cmath
#include array
#include algorithm// #define constexpr
//return 之后才会调用所有成员的析构函数
constexpr int func(int n)
{ int *pnew int[n]{};struct guard{int* p;constexpr ~guard() noexcept{delete[] p;}}_v(p);return p[0];
}int main()
{// constexpr int _1 func(0);constexpr int _2 func(1);printf(%d\n,_2);return 0;
}使用constexpr检测UB
#include cstdio
#include cmath
#include array
#include algorithm// #define constexprconstexpr int func(int n)
{ int *pnew int[n]{};delete[] p;delete[] p;return p[0];
}int main()
{// constexpr int _1 func(0);constexpr int _2 func(1);printf(%d\n,_2);return 0;
}编译及运行
source: In function int main():
source:19:28: in constexpr expansion of func(1)
source:12:14: error: deallocation of already deallocated storage12 | delete[] p;| delete 空指针不会造成UB #include cstdio
#include cmath
#include array
#include algorithm// #define constexprconstexpr int func(int n)
{ int *pnullptr;delete p;return 0;
}int main()
{// constexpr int _1 func(0);constexpr int _2 func(1);printf(%d\n,_2);return 0;
}5.vector
#include cstdio
#include cmath
#include array
#include algorithm
#include vector// #define constexprconstexpr int func(int n)
{ std::vectorint v(n);return v[0];
}int main()
{constexpr int _1 func(0);constexpr int _2 func(1);printf(%d\n,_2);return 0;
}编译及运行
In file included from /opt/compiler-explorer/gcc-13.2.0/include/c/13.2.0/vector:66,from source:5:
/opt/compiler-explorer/gcc-13.2.0/include/c/13.2.0/bits/stl_vector.h: In function int main():
source:17:28: in constexpr expansion of func(0)
source:12:15: in constexpr expansion of v.std::vectorint::operator[](0)
/opt/compiler-explorer/gcc-13.2.0/include/c/13.2.0/bits/stl_vector.h:1126:41: error: dereferencing a null pointer1126 | return *(this-_M_impl._M_start __n);| ~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~std::vector v(n);并不将所有成员都初始化为0vector的resize()方法可以初始化vector内部的成员都初始化为0 #include cstdio
#include cmath
#include array
#include algorithm
#include vector// #define constexprconstexpr int func(int n)
{ std::vectorint v(n);v.reserve(2);v.resize(20);return v[0];
}int main()
{constexpr int _1 func(0);constexpr int _2 func(1);// std::vectorint v(0);// v.reserve(20);// v.resize(2);// printf(%u\n, v.size());// printf(%u\n, v.capacity());printf(%d\n,_2);return 0;
}6.空指针解引用
#include cstdio
#include cmath
#include array
#include algorithm
#include vector// #define constexprconstexpr int func(int n)
{ int* pnullptr;return *p;
}int main()
{constexpr int _1 func(0);constexpr int _2 func(1);printf(%d\n,_2);return 0;
}编译及运行
source: In function int main():
source:17:28: in constexpr expansion of func(0)
source:17:30: error: dereferencing a null pointer17 | constexpr int _1 func(0);| ^
source:18:28: in constexpr expansion of func(1)
source:18:30: error: dereferencing a null pointer18 | constexpr int _2 func(1);| ^参考
【C20】编译期检测所有未定义行为和内存泄漏不借助任何外部工具