Unknown Bounded Array

博客讨论了在C++中数组声明与定义不匹配可能导致的问题,以及将数组声明为指针的尝试所带来的段错误。文章解释了这个问题的原因,即64位指针误解了数组的前两个元素为地址。提出了解决方案,即使用不完整类(UnknownBoundedArray)来避免此类问题,允许声明不指定大小的数组。

有两个文件,一个文件是数组的声明,另一个是数组的定义。如果数组的定义发生变化,比如说变成了含有5个元素的数组,那么相关联的声明也必须改变。一旦文件变多则会有部分文件忘记修改,就会发生意想不到的问题。

int array[4] = { 1, 2, 3, 4 };
#include<iostream>
extern int array[4];

int main()
{
	……
	return 0;
}

有的人想出一种解决办法,声明成指针。因为数组会隐式类型转换为指针,但这种解决方法会出现一个段错误(如果对array指针解引用的话),我们先看程序,顺便把各元素的地址打印出来:

#include<iostream>

int array[4] = { 1, 2, 3, 4 };
void func()
{
	std::cout << array << std::endl;
}
#include<iostream>

void func();
extern int* array;

int main()
{
	func();
	//std::cout << array[1] << std::endl;
	std::cout << array << std::endl;
	return 0;
}

在这里插入图片描述

很显然,第一个地址才符合C++语言的地址形式。那么为什么会出现这种问题呢?

首先这个不是编译错误,因为各文件单独编译都没有问题;其次也不是链接问题(类型是在编译器的概念,链接中是没有类型的,只有符号),array符号一致;因此它是一个运行错误。因为指针是64位的,所以它会把数组的前两个元素看成指针(由于大小端原因),而直接转换的地址是无效的,所以解引用会发生段错误。

在这里插入图片描述

正确的做法是使用Unknown Bounded Array(C++专门的术语叫不完整类):

#include<iostream>

int array[4] = { 1, 2, 3, 4 };
void func()
{
	std::cout << array << std::endl;
}
#include<iostream>

void func();
extern int array[];//声明可以这样写,但定义不能

int main()
{
	func();
	std::cout << array << std::endl;
	return 0;
}
严重性 代码 说明 项目 文件 行 禁止显示状态 错误 C2088 “[”: 对于 class 非法 GeoClip D:\local\clip\code\main.cpp 72 错误(活动) E1835 特性 "maybe_unused" 在此处不适用 GeoClip C:\Users\fuwei\.conda\envs\gisenvv\Library\include\boost\lambda\core.hpp 71 错误(活动) E1835 特性 "maybe_unused" 在此处不适用 GeoClip C:\Users\fuwei\.conda\envs\gisenvv\Library\include\boost\lambda\core.hpp 72 错误(活动) E1835 特性 "maybe_unused" 在此处不适用 GeoClip C:\Users\fuwei\.conda\envs\gisenvv\Library\include\boost\lambda\core.hpp 73 错误(活动) E0070 不允许使用不完整的类型 GeoClip D:\Program Files (x86)\Microsoft Visual Studio\2019\Professional\VC\Tools\MSVC\14.29.30133\include\array 594 警告 C26812 枚举类型“CGAL::Failure_behaviour”未设定范围。相比于 "enum",首选 "enum class" (Enum.3)。 GeoClip C:\Users\fuwei\.conda\envs\gisenvv\Library\include\CGAL\assertions_impl.h 40 警告 C26812 枚举类型“CGAL::Sign”未设定范围。相比于 "enum",首选 "enum class" (Enum.3)。 GeoClip C:\Users\fuwei\.conda\envs\gisenvv\Library\include\CGAL\enum.h 73 警告 C26812 枚举类型“CGAL::Bounded_side”未设定范围。相比于 "enum",首选 "enum class" (Enum.3)。 GeoClip C:\Users\fuwei\.conda\envs\gisenvv\Library\include\CGAL\enum.h 78 警告 C26812 枚举类型“CGAL::Angle”未设定范围。相比于 "enum",首选 "enum class" (Enum.3)。 GeoClip C:\Users\fuwei\.conda\envs\gisenvv\Library\include\CGAL\enum.h 83 警告 C4819 该文件包含不能在当前代码页(936)中表示的字符。请将该文件保存为 Unicode 格式以防止数据丢失 GeoClip D:\local\clip\code\main.cpp 1 警告 C4819 该文件包含不能在当前代码页(936)中表示的字符。请将该文件保存为 Unicode 格式以防止数据丢失 GeoClip C:\Users\fuwei\.conda\envs\gisenvv\Library\include\eigen3\Eigen\src\Core\arch\Default\Half.h 1 警告 C4819 该文件包含不能在当前代码页(936)中表示的字符。请将该文件保存为 Unicode 格式以防止数据丢失 GeoClip C:\Users\fuwei\.conda\envs\gisenvv\Library\include\eigen3\Eigen\src\Core\arch\Default\BFloat16.h 1 警告 C4819 该文件包含不能在当前代码页(936)中表示的字符。请将该文件保存为 Unicode 格式以防止数据丢失 GeoClip C:\Users\fuwei\.conda\envs\gisenvv\Library\include\eigen3\Eigen\src\Core\arch\Default\GenericPacketMathFunctions.h 676 警告 C4819 该文件包含不能在当前代码页(936)中表示的字符。请将该文件保存为 Unicode 格式以防止数据丢失 GeoClip C:\Users\fuwei\.conda\envs\gisenvv\Library\include\CGAL\boost\graph\Euler_operations.h 1 警告 C4819 该文件包含不能在当前代码页(936)中表示的字符。请将该文件保存为 Unicode 格式以防止数据丢失 GeoClip C:\Users\fuwei\.conda\envs\gisenvv\Library\include\CGAL\boost\graph\Euler_operations.h 1 警告 C4819 该文件包含不能在当前代码页(936)中表示的字符。请将该文件保存为 Unicode 格式以防止数据丢失 GeoClip C:\Users\fuwei\.conda\envs\gisenvv\Library\include\boost\random\mixmax.hpp 1 警告 C4819 该文件包含不能在当前代码页(936)中表示的字符。请将该文件保存为 Unicode 格式以防止数据丢失 GeoClip C:\Users\fuwei\.conda\envs\gisenvv\Library\include\boost\random\detail\mixmax_skip_N17.ipp 1 错误 C2653 “Kernel”: 不是类或命名空间名称 GeoClip D:\local\clip\code\main.cpp 33 错误 C4430 缺少类型说明符 - 假定为 int。注意: C++ 不支持默认 int GeoClip D:\local\clip\code\main.cpp 33 错误 C2146 语法错误: 缺少“;”(在标识符“Point_2”的前面) GeoClip D:\local\clip\code\main.cpp 33 警告 C4091 “”: 没有声明变量时忽略“int”的左侧 GeoClip D:\local\clip\code\main.cpp 33 错误 C2039 "SM_Vertex_index": 不是 "CGAL" 的成员 GeoClip D:\local\clip\code\main.cpp 34 错误 C4430 缺少类型说明符 - 假定为 int。注意: C++ 不支持默认 int GeoClip D:\local\clip\code\main.cpp 34 错误 C2146 语法错误: 缺少“;”(在标识符“VertexIndex”的前面) GeoClip D:\local\clip\code\main.cpp 34 错误 C2653 “Kernel”: 不是类或命名空间名称 GeoClip D:\local\clip\code\main.cpp 37 错误 C4430 缺少类型说明符 - 假定为 int。注意: C++ 不支持默认 int GeoClip D:\local\clip\code\main.cpp 37 错误 C2146 语法错误: 缺少“;”(在标识符“Vector_3”的前面) GeoClip D:\local\clip\code\main.cpp 37 警告 C4091 “”: 没有声明变量时忽略“int”的左侧 GeoClip D:\local\clip\code\main.cpp 37 错误 C2653 “Kernel”: 不是类或命名空间名称 GeoClip D:\local\clip\code\main.cpp 38 错误 C4430 缺少类型说明符 - 假定为 int。注意: C++ 不支持默认 int GeoClip D:\local\clip\code\main.cpp 38 错误 C2146 语法错误: 缺少“;”(在标识符“Plane_3”的前面) GeoClip D:\local\clip\code\main.cpp 38 警告 C4091 “”: 没有声明变量时忽略“int”的左侧 GeoClip D:\local\clip\code\main.cpp 38 错误 C2653 “Kernel”: 不是类或命名空间名称 GeoClip D:\local\clip\code\main.cpp 39 错误 C4430 缺少类型说明符 - 假定为 int。注意: C++ 不支持默认 int GeoClip D:\local\clip\code\main.cpp 39 错误 C2146 语法错误: 缺少“;”(在标识符“Aff_transformation_3”的前面) GeoClip D:\local\clip\code\main.cpp 39 警告 C4091 “”: 没有声明变量时忽略“int”的左侧 GeoClip D:\local\clip\code\main.cpp 39 错误 C2039 "Optimal_bounding_box": 不是 "CGAL" 的成员 GeoClip D:\local\clip\code\main.cpp 40 错误 C2878 “Optimal_bounding_box”: 该名称的命名空间或类不存在 GeoClip D:\local\clip\code\main.cpp 40 错误 C2143 语法错误: 缺少“;”(在“&”的前面) GeoClip D:\local\clip\code\main.cpp 48 错误 C4430 缺少类型说明符 - 假定为 int。注意: C++ 不支持默认 int GeoClip D:\local\clip\code\main.cpp 48 错误 C2238 意外的标记位于“;”之前 GeoClip D:\local\clip\code\main.cpp 48 错误 C2653 “CGALMesh”: 不是类或命名空间名称 GeoClip D:\local\clip\code\main.cpp 49 错误 C2065 “Vertex_index”: 未声明的标识符 GeoClip D:\local\clip\code\main.cpp 49 错误 C2653 “CGALMesh”: 不是类或命名空间名称 GeoClip D:\local\clip\code\main.cpp 49 错误 C2065 “Vertex_index”: 未声明的标识符 GeoClip D:\local\clip\code\main.cpp 49 错误 C2923 “std::map”: 对于参数“_Kty”,“Vertex_index”不是有效的 模板 类型变量 GeoClip D:\local\clip\code\main.cpp 49 错误 C2923 “std::map”: 对于参数“_Ty”,“Vertex_index”不是有效的 模板 类型变量 GeoClip D:\local\clip\code\main.cpp 49 错误 C2976 “std::map”: 模板 参数太少 GeoClip D:\local\clip\code\main.cpp 49 错误 C2955 “std::map”: 使用 类 模板 需要 模板 参数列表 GeoClip D:\local\clip\code\main.cpp 49 错误 C2061 语法错误: 标识符“CGALMesh” GeoClip D:\local\clip\code\main.cpp 50 错误 C3646 “TriangleMesh”: 未知重写说明符 GeoClip D:\local\clip\code\main.cpp 52 错误 C4430 缺少类型说明符 - 假定为 int。注意: C++ 不支持默认 int GeoClip D:\local\clip\code\main.cpp 52 错误 C2653 “GT”: 不是类或命名空间名称 GeoClip D:\local\clip\code\main.cpp 53 错误 C3646 “halfedge_descriptor”: 未知重写说明符 GeoClip D:\local\clip\code\main.cpp 53 错误 C4430 缺少类型说明符 - 假定为 int。注意: C++ 不支持默认 int GeoClip D:\local\clip\code\main.cpp 53 错误 C2061 语法错误: 标识符“face_descriptor” GeoClip D:\local\clip\code\main.cpp 55 错误 C2061 语法错误: 标识符“TriangleMesh” GeoClip D:\local\clip\code\main.cpp 56 错误 C2061 语法错误: 标识符“TriangleMesh” GeoClip D:\local\clip\code\main.cpp 57 错误 C2061 语法错误: 标识符“face_descriptor” GeoClip D:\local\clip\code\main.cpp 58 错误 C2061 语法错误: 标识符“face_descriptor” GeoClip D:\local\clip\code\main.cpp 59 错误 C2061 语法错误: 标识符“face_descriptor” GeoClip D:\local\clip\code\main.cpp 60 错误 C2061 语法错误: 标识符“TriangleMesh” GeoClip D:\local\clip\code\main.cpp 77 错误 C2061 语法错误: 标识符“TriangleMesh” GeoClip D:\local\clip\code\main.cpp 78 错误 C2061 语法错误: 标识符“TriangleMesh” GeoClip D:\local\clip\code\main.cpp 81 错误 C4430 缺少类型说明符 - 假定为 int。注意: C++ 不支持默认 int GeoClip D:\local\clip\code\main.cpp 83 错误 C2143 语法错误: 缺少“,”(在“&”的前面) GeoClip D:\local\clip\code\main.cpp 83 错误 C4430 缺少类型说明符 - 假定为 int。注意: C++ 不支持默认 int GeoClip D:\local\clip\code\main.cpp 84 错误 C2143 语法错误: 缺少“,”(在“&”的前面) GeoClip D:\local\clip\code\main.cpp 84 错误 C2061 语法错误: 标识符“TriangleMesh” GeoClip D:\local\clip\code\main.cpp 87 错误 C2061 语法错误: 标识符“TriangleMesh” GeoClip D:\local\clip\code\main.cpp 89 错误 C4430 缺少类型说明符 - 假定为 int。注意: C++ 不支持默认 int GeoClip D:\local\clip\code\main.cpp 91 错误 C2143 语法错误: 缺少“,”(在“&”的前面) GeoClip D:\local\clip\code\main.cpp 91 错误 C2061 语法错误: 标识符“vertex_descriptor” GeoClip D:\local\clip\code\main.cpp 96 错误 C4430 缺少类型说明符 - 假定为 int。注意: C++ 不支持默认 int GeoClip D:\local\clip\code\main.cpp 106 错误 C2143 语法错误: 缺少“,”(在“&”的前面) GeoClip D:\local\clip\code\main.cpp 106 错误 C2061 语法错误: 标识符“vertex_descriptor” GeoClip D:\local\clip\code\main.cpp 110 错误 C2061 语法错误: 标识符“vertex_descriptor” GeoClip D:\local\clip\code\main.cpp 111 错误 C4430 缺少类型说明符 - 假定为 int。注意: C++ 不支持默认 int GeoClip D:\local\clip\code\main.cpp 141 错误 C2143 语法错误: 缺少“,”(在“&”的前面) GeoClip D:\local\clip\code\main.cpp 141 错误 C2653 “PMP”: 不是类或命名空间名称 GeoClip D:\local\clip\code\main.cpp 142 错误 C2061 语法错误: 标识符“Boolean_operation_type” GeoClip D:\local\clip\code\main.cpp 142 错误 C2653 “PMP”: 不是类或命名空间名称 GeoClip D:\local\clip\code\main.cpp 143 错误 C2061 语法错误: 标识符“Boolean_operation_type” GeoClip D:\local\clip\code\main.cpp 143 错误 C2653 “PMP”: 不是类或命名空间名称 GeoClip D:\local\clip\code\main.cpp 144 错误 C2061 语法错误: 标识符“Boolean_operation_type” GeoClip D:\local\clip\code\main.cpp 144 错误 C2065 “sm”: 未声明的标识符 GeoClip D:\local\clip\code\main.cpp 50 错误 C2512 “std::map”: 没有合适的默认构造函数可用 GeoClip D:\local\clip\code\main.cpp 50 错误 C2614 “SectionVisitor”: 非法的成员初始化:“section”不是基或成员 GeoClip D:\local\clip\code\main.cpp 50 错误 C2825 'SectionVisitor::CGALMesh': 当后面跟“::”时必须为类或命名空间 GeoClip D:\local\clip\code\main.cpp 63 错误 C2510 “CGALMesh”:“::”的左边必须是类/结构/联合 GeoClip D:\local\clip\code\main.cpp 63 错误 C2065 “Vertex_index”: 未声明的标识符 GeoClip D:\local\clip\code\main.cpp 63 错误 C2923 “std::vector”: 对于参数“_Ty”,“Vertex_index”不是有效的 模板 类型变量 GeoClip D:\local\clip\code\main.cpp 63 错误 C2976 “std::vector”: 模板 参数太少 GeoClip D:\local\clip\code\main.cpp 63 错误 C2641 无法推导“std::vector”的模板参数 GeoClip D:\local\clip\code\main.cpp 63 错误 C2783 “std::vector<_Ty,_Alloc> std::vector(void) noexcept(<expr>)”: 未能为“_Ty”推导 模板 参数 GeoClip D:\local\clip\code\main.cpp 63 错误 C2780 “std::vector<_Ty,_Alloc> std::vector(std::vector<_Ty,_Alloc>)”: 应输入 1 个参数,却提供了 0 个 GeoClip D:\local\clip\code\main.cpp 63 错误 C2065 “tm_old”: 未声明的标识符 GeoClip D:\local\clip\code\main.cpp 64 错误 C2065 “f_old”: 未声明的标识符 GeoClip D:\local\clip\code\main.cpp 64 错误 C2065 “tm_old”: 未声明的标识符 GeoClip D:\local\clip\code\main.cpp 64 错误 C3861 “vertices_around_face”: 找不到标识符 GeoClip D:\local\clip\code\main.cpp 64 错误 C2672 “begin”: 未找到匹配的重载函数 GeoClip D:\local\clip\code\main.cpp 64 错误 C2893 未能使函数模板“unknown-type std::begin(_Container &)”专用化 GeoClip D:\local\clip\code\main.cpp 64 错误 C2784 “const _Elem *std::begin(std::initializer_list<_Elem>) noexcept”: 未能从“unknown-type”为“std::initializer_list<_Elem>”推导 模板 参数 GeoClip D:\local\clip\code\main.cpp 64 错误 C2672 “end”: 未找到匹配的重载函数 GeoClip D:\local\clip\code\main.cpp 64 错误 C2893 未能使函数模板“unknown-type std::end(_Container &)”专用化 GeoClip D:\local\clip\code\main.cpp 64 错误 C2784 “const _Elem *std::end(std::initializer_list<_Elem>) noexcept”: 未能从“unknown-type”为“std::initializer_list<_Elem>”推导 模板 参数 GeoClip D:\local\clip\code\main.cpp 64 错误 C3536 “<begin>$L0”: 初始化之前无法使用 GeoClip D:\local\clip\code\main.cpp 64 错误 C3536 “<end>$L0”: 初始化之前无法使用 GeoClip D:\local\clip\code\main.cpp 64 错误 C2100 非法的间接寻址 GeoClip D:\local\clip\code\main.cpp 64 错误 C2039 "find": 不是 "std::map" 的成员 GeoClip D:\local\clip\code\main.cpp 65 错误 C3536 “it”: 初始化之前无法使用 GeoClip D:\local\clip\code\main.cpp 66 错误 C2039 "end": 不是 "std::map" 的成员 GeoClip D:\local\clip\code\main.cpp 66 错误 C2663 “std::vector<_Ty,_Alloc>::push_back”: 2 个重载没有“this”指针的合法转换 GeoClip D:\local\clip\code\main.cpp 67 错误 C2662 “allocator_traits<allocator_traits<_Alloc>::rebind_alloc<_Ty>>::size_type std::vector<_Ty,_Alloc>::size(void) noexcept const”: 不能将“this”指针从“std::vector”转换为“const std::vector<_Ty,_Alloc> &” GeoClip D:\local\clip\code\main.cpp 71 错误 C2065 “section”: 未声明的标识符 GeoClip D:\local\clip\code\main.cpp 72 错误 C2678 二进制“[”: 没有找到接受“std::vector”类型的左操作数的运算符(或没有可接受的转换) GeoClip D:\local\clip\code\main.cpp 72 错误 C2088 “[”: 对于 class 非法 GeoClip D:\local\clip\code\main.cpp 72 错误 C2065 “vh”: 未声明的标识符 GeoClip D:\local\clip\code\main.cpp 99 错误 C2065 “section”: 未声明的标识符 GeoClip D:\local\clip\code\main.cpp 99 错误 C2275 “tm”: 将此类型用作表达式非法 GeoClip D:\local\clip\code\main.cpp 99 错误 C2065 “vh”: 未声明的标识符 GeoClip D:\local\clip\code\main.cpp 99 错误 C2065 “v_src”: 未声明的标识符 GeoClip D:\local\clip\code\main.cpp 114 错误 C2065 “section”: 未声明的标识符 GeoClip D:\local\clip\code\main.cpp 114 错误 C2065 “tm_src”: 未声明的标识符 GeoClip D:\local\clip\code\main.cpp 114 错误 C2065 “v_src”: 未声明的标识符 GeoClip D:\local\clip\code\main.cpp 114 错误 C2065 “Point”: 未声明的标识符 GeoClip D:\local\clip\code\main.cpp 155 错误 C2923 “std::vector”: 对于参数“_Ty”,“Point”不是有效的 模板 类型变量 GeoClip D:\local\clip\code\main.cpp 155 错误 C2976 “std::vector”: 模板 参数太少 GeoClip D:\local\clip\code\main.cpp 155 错误 C2955 “std::vector”: 使用 类 模板 需要 模板 参数列表 GeoClip D:\local\clip\code\main.cpp 155 错误 C2079 “readCurve”使用未定义的 class“std::vector” GeoClip D:\local\clip\code\main.cpp 155 错误 C2065 “Point”: 未声明的标识符 GeoClip D:\local\clip\code\main.cpp 156 错误 C2923 “std::vector”: 对于参数“_Ty”,“Point”不是有效的 模板 类型变量 GeoClip D:\local\clip\code\main.cpp 156 错误 C2976 “std::vector”: 模板 参数太少 GeoClip D:\local\clip\code\main.cpp 156 错误 C2641 无法推导“std::vector”的模板参数 GeoClip D:\local\clip\code\main.cpp 156 错误 C1003 错误计数超过 100;正在停止编译 GeoClip D:\local\clip\code\main.cpp 156
09-20
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值