C/C++--one

C和C++的关系

(1)在C++程序中调用被C编译器编译后的函数,为什么要加extern “C”?
  C++支持函数重载,C语言不支持。函数在被C++编译后在库中的名字与C语言不同。
例如:函数原型为void foo(int x,int y),则该函数被C编译器编译后在库中的名字为_foo,而C++编译器则会产生像_foo_int_int这类的名字。
C++提供C连接交换制定符号extern“C”解决名字匹配问题。

(2)ifndef/define/endif是干什么的?
  防止头文件被反复引用。

预处理、const与sizeof

(1)const主要有哪些作用?
const修饰的类型是常类型,常类型的变量或对值的值是不可更新的。

  • 可以定义const常量,具有不可变性。
  • 便于类型检测,使处理器对处理内容有更多了解。
  • 可以避免意义模糊的数组出现。
  • 可以保护被修改的内容,防止意外的修改。
  • 用于函数重载。
  • 可节省空间,避免不必要的内存分配。
  • 提高了效率(编译器不为普通const常量分配空间,而是保持在符号表中,只保存一份)

const成员函数是什么
  在类中常常有一些成员函数不改变类的数据成员,也就是说这些函数是“只读”函数,而有一些函数要修改数据成员的值。如果把不改变数据成员的成员函数加上const进行标识,可提高程序可读性。一旦函数内试图修改成员函数的值,则编译器会报错。

(2)const和#define有什么不同?
C++中,它们都可以定义常量,但const比#define有更多优点。

  • const数据有数据类型,而宏常量没有数据类型。编译器可以对前者进行类型安全检测,而对后者只能进行字符替换,并且在字符替换中可能会产生意料不到的错误。、
  • const常量可以调试,而宏常量不能调试,在C++中,只使用const不适用#define,也就是用const完全取代宏

(3)inline和宏定义的差别是什么?
  内敛函数相比普通函数可以加快程序运行速度,因为不需要中断调用,在编译期间内敛函数可以直接被嵌入到目标代码中,而宏只是一个简单的替换。
  内联函数要做安全类型检测,这是内敛相比宏的优势。
内敛适用与如下场景:
①一个函数不断被重复调用
②函数简短,且没有for、while、swatic语句。

指针和引用

(1)指针和引用的差别?

  • 指针是一个变量,有自身的储存地址。引用只不过是原变量的别名。
  • 非空区别。指针可以为空,引用必须定义时初始化。
  • 合法性检测。在使用引用之前不需要检测它的合法性,而指针总需要判空。
  • 可修改区别。指针可以被重新赋值以指向另一个不同的对象。但是引用是“从一而终“。
  • sizeof指针和引用以及对他们进行自增的意义不同。

(2)C++中有了malloc/free,为什么还需要new/delete?
  malloc与free是C/C++的标准库函数,new/delete是C++的运算符。它们都可用于申请动态内存和释放内存。
  对于非内部数据类型的对象而言,只用malloc/free无法满足动态对象的要求。对象在创建的同时要自动执行构造函数,对象在消亡之前要自动执行析构函数。由于malloc/free是库函数而不是运算符,不在编译器控制权限之内,不能够把执行构造函数和析构函数的任务强加与malloc/free。
new和malloc的区别

(3)指针和句柄的区别和联系是什么?
  句柄和指针其实是两个截然不同的概念。windows系统用句柄标记系统资源,隐藏系统的信息,。你只要知道有这个东西然后调用就可以了,他说一个32bit的uint。指针则标记某物理内存地址,两者是不同的概念。

(4)this指针相关问题
 ①this指针本质是一个函数参数,只是编译器隐藏起形式的,语法层面上的参数。
this指针只能在成员函数中使用,全局函数、静态函数都不能使用this。
事实上成员函数默认第一个参数为T* const this。
 ②this指针在成员函数的开始前构造,在成员的结束后清除。这个生命周期同任何一个函数的参数是一样的,没有任何区别。当调用一个类的成员函数时,编译器将类的指针作为函数的this参数传递进去。
 ③this指针并不占用对象的空间
this相当于一个非静态成员函数的一个隐含的参数,不占对象的空间。他跟对象之间没有包含关系,只是当前调用函数的对象被它指向而已。
 ④this指针是什么时候创建的?
this在成员函数的开始前构造,在成员的执行结束后清除。
 ⑤this指针是如何传递给类中的函数的?绑定?还是在函数参数的首参数就是this指针?那么,this指针又是如何找到“类实例后的函数”的?
  大多数编译器通过eax寄存器传递this指针。事实上,这也是一个潜规则。一般来说,不同编译器都会遵从一致的传参规则,否则不同编译器产生的obj就无法匹配了。
  在call之前,编译器会把对应的对象地址放到eax中。this是通过函数参数的首参数来传递的。

<think>我们正在处理一个关于CMake配置错误的问题,具体错误是“BOARD not defined”。用户希望使用交叉编译器为ARM构建libgcc和stdc++的静态库。根据用户提供的信息,错误发生在配置阶段,因为CMake变量BOARD未定义。 首先,我们需要明确BOARD变量在CMake脚本中的作用。通常,在嵌入式开发中,BOARD变量用于指定目标硬件平台,以便选择正确的编译器选项、链接脚本和特定于板的配置。 根据用户的问题,他正在尝试构建libgcc和stdc++的静态库。这通常发生在构建交叉工具链或为特定目标构建标准库时。 解决方案步骤: 1. 检查CMake命令是否提供了定义BOARD变量的选项。例如,在CMake中,可以通过-D选项定义变量: ``` cmake -DBOARD=your_board_name .. ``` 2. 如果用户不知道具体的BOARD值,需要查看项目的文档或CMakeLists.txt文件,了解支持哪些板以及如何设置。 3. 另一种可能性是项目期望通过环境变量设置BOARD。在这种情况下,可以在运行CMake之前设置环境变量: - 在Linux/macOS上:`export BOARD=your_board_name` - 在Windows上:`set BOARD=your_board_name` 4. 如果项目本身没有要求BOARD变量,那么可能是CMake脚本中的一个错误。需要检查CMakeLists.txt,看看在什么条件下会使用BOARD变量,以及在没有定义时是否提供了合理的默认值。 5. 用户的问题中提到“交叉编译器”,因此我们还需要确保交叉编译工具链已正确设置。通常,在运行CMake之前,需要指定工具链文件(toolchain file)。工具链文件中会设置编译器路径、目标平台等。例如: ``` cmake -DCMAKE_TOOLCHAIN_FILE=path/to/toolchain-file.cmake .. ``` 6. 在工具链文件中,可能需要设置BOARD变量,或者确保工具链文件中的设置与BOARD变量无关。 7. 如果用户的项目是某个已知的嵌入式项目(如Zephyr RTOS),那么BOARD变量是必须的。Zephyr项目就需要在构建时指定BOARD。 由于用户没有提供具体的项目信息,我们只能给出一般性的建议。 考虑到用户上一次的问题是关于构建libgcc和stdc++静态库,我们可以推测他可能在构建交叉编译工具链或者是为某个嵌入式项目构建标准库。 如果用户正在构建的是gcc本身,那么通常不需要BOARD变量。因此,这个错误可能出现在一个特定的项目中。 建议用户: - 检查项目的README或文档,看是否有关于BOARD设置的说明。 - 查看CMakeLists.txt文件,搜索BOARD变量,了解其用途和期望的值。 如果用户能够提供更多信息(例如项目来源),我们可以给出更具体的指导。 现在,生成相关问题: 1. 如何为ARM交叉编译设置CMake工具链文件? 2. 在嵌入式项目中,BOARD变量通常用于什么目的? 3. 如何解决CMake中未定义的变量错误? 4. 构建libgcc和stdc++静态库的常见步骤是什么?</think>### 解决CMake配置错误:BOARD未定义问题 当为ARM交叉编译构建libgcc和stdc++静态库时出现`BOARD not defined`错误,通常是因为CMake缺少关键平台定义。以下是系统解决方案: #### 核心解决步骤 1. **显式定义BOARD变量** 在CMake命令中通过`-D`参数指定目标板: ```bash cmake -DBOARD=your_target_board_name -DCMAKE_TOOLCHAIN_FILE=arm-toolchain.cmake .. ``` 将`your_target_board_name`替换为实际开发板名称(如`stm32f4-discovery`) 2. **配置工具链文件** 创建`arm-toolchain.cmake`文件(示例): ```cmake set(CMAKE_SYSTEM_NAME Generic) set(CMAKE_SYSTEM_PROCESSOR arm) set(CMAKE_C_COMPILER arm-none-eabi-gcc) set(CMAKE_CXX_COMPILER arm-none-eabi-g++) set(CMAKE_ASM_COMPILER arm-none-eabi-gcc) set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) ``` 3. **添加标准库配置** 在CMakeLists.txt中强制链接静态库: ```cmake # 添加静态库目标 add_library(libgcc STATIC IMPORTED) set_target_properties(libgcc PROPERTIES IMPORTED_LOCATION "${TOOLCHAIN_DIR}/lib/gcc/arm-none-eabi/12.2.1/libgcc.a" ) # 链接到可执行文件 target_link_libraries(your_target PRIVATE libgcc -lc -lstdc++ ) ``` 4. **验证构建环境** 检查工具链路径是否包含libgcc.a: ```bash find $ARM_TOOLCHAIN_DIR -name libgcc.a ``` #### 常见错误原因 - **交叉编译器未配置**:缺少`-DCMAKE_TOOLCHAIN_FILE`参数 - **板级支持包(BSP)缺失**:开发板定义未包含在工程中 - **路径错误**:工具链路径未正确导出,需设置: ```bash export PATH=$PATH:/opt/arm/gcc-arm-none-eabi-12.2/bin ``` > **关键提示**:对于ARM Cortex-M系列,建议添加`-specs=nosys.specs`链接器标志以处理系统调用[^1]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值