189页习题6.23一个产生overflow_error异常的程序

//为了方便,要包含的文件会不同,但我没有删
#include <iostream>
#include <string>
#include <vector>
#include <bitset>
#include <cstring>   //和C语言的string.h其实是一个版本
#include <exception>

using std::bitset;
using std::vector;
using std::cin;
using std::endl;
using std::cout;
using std::string;
using std::overflow_error;

//---------------------------------------------------------------------------

    int main()
    {
 
  

 bitset<32> bitvec32;
  bitset<38> bitvec38;

  bitvec32.set();
  bitvec38.set();


  unsigned long ul=0;

if(bitvec38.size()>sizeof(ul))
throw overflow_error("bitvec太大,无法转换为unsigned long");


 ul=bitvec38.to_ulong();
  cout<<"ul="<<ul<<endl;

 
       return 0;
    }

 /*
         189页习题6.23一个产生overflow_error异常的程序
 */

### Keil v6.23 中 `__bss_end` 相关问题的解决方案 在使用 Keil v6.23 编译器时,如果遇到与 `__bss_end` 相关的问题,通常是由于链接脚本或编译选项配置不当导致的。以下是对该问题的详细分析和解决方案: #### 1. 问题背景 `__bss_end` 是一个由编译器生成的符号,用于标记 BSS 段的结束位置[^1]。BSS 段是程序中未初始化全局变量和静态变量的存储区域。当编译器无法正确解析 `__bss_end` 符号时,通常会报错,提示类似“undefined reference to `__bss_end`”的错误。 #### 2. 可能的原因 - **链接脚本问题**:链接脚本中未正确定义 BSS 段的范围,导致编译器无法生成 `__bss_end` 符号。 - **编译选项问题**:某些优化选项(如 `-ffunction-sections` 和 `-fdata-sections`)可能导致部分符号被裁剪掉,从而引发未定义符号的问题。 - **库文件缺失**:某些项目依赖的库文件中可能包含对 `__bss_end` 的引用,若缺少这些库文件,也会导致此问题。 #### 3. 解决方案 ##### (1) 检查链接脚本 确保链接脚本中正确定义了 BSS 段,并明确指定了 `__bss_start` 和 `__bss_end` 符号的位置。以下是一个典型的 BSS 段定义示例: ```ld /* 链接脚本中的 BSS 段定义 */ .bss : { . = ALIGN(4); __bss_start = .; /* 定义 BSS 段起始地址 */ *(.bss) *(COMMON) . = ALIGN(4); __bss_end = .; /* 定义 BSS 段结束地址 */ } > SRAM ``` 上述代码片段中,`__bss_start` 和 `__bss_end` 分别表示 BSS 段的起始和结束位置[^3]。确保链接脚本中包含类似的定义。 ##### (2) 调整编译选项 如果项目启用了 `-ffunction-sections` 和 `-fdata-sections` 选项,则需要在链接阶段添加 `--gc-sections` 选项,以防止不必要的代码和数据段被裁剪掉。以下是完整的编译和链接选项示例: ```makefile CFLAGS = $(ARCH_FLAGS) $(DEFS) $(INCDIR) -ffunction-sections -fdata-sections -g -O1 -std=gnu99 LDFLAGS = --gc-sections ``` 通过上述设置,可以避免因符号裁剪而导致的未定义问题。 ##### (3) 确保库文件完整 检查项目是否依赖某些外部库文件(如 `system_gd32f10x.o`),并确保这些库文件已正确添加到项目中。若缺少必要的库文件,可能会导致类似 `SystemInit` 或 `__bss_end` 的符号未定义问题[^1]。 ##### (4) 手动定义符号 如果以上方法均无效,可以尝试手动定义 `__bss_end` 符号。在项目的启动文件(如 `startup.s` 或 `startup.c`)中添加以下代码: ```c extern unsigned char __bss_start; extern unsigned char __bss_end; void SystemInit(void) { // 初始化代码 } void Reset_Handler(void) { unsigned char *p = &__bss_start; while (p < &__bss_end) { *p++ = 0; // 清零 BSS 段 } } ``` 上述代码片段中,`__bss_start` 和 `__bss_end` 被声明为外部符号,并在 `Reset_Handler` 函数中清零 BSS 段的内容。 #### 4. 示例代码 以下是一个完整的 Keil 工程配置示例: ```makefile # 编译选项 CFLAGS = $(ARCH_FLAGS) $(DEFS) $(INCDIR) -ffunction-sections -fdata-sections -g -O1 -std=gnu99 # 链接选项 LDFLAGS = --gc-sections # 链接脚本 LDSCRIPT = linker.ld # 源文件列表 SRC = main.c system_gd32f10x.c startup.c # 目标文件 TARGET = project.elf all: $(TARGET) $(TARGET): $(SRC) arm-none-eabi-gcc $(CFLAGS) -T $(LDSCRIPT) $(LDFLAGS) -o $@ $^ ``` #### 5. 注意事项 - 确保链接脚本中定义的内存区域(如 `SRAM`)与目标芯片的实际内存布局一致。 - 如果使用了自定义的启动代码,请确保其正确初始化了 BSS 段和数据段。 ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值