【C/C++】C语言工程转C++工程,去除旧代码中的警告和错误

简介: 将 C语言项目转为C++项目更新维护,处理旧代码中的警告和错误

【C/C++】C语言工程转C++工程,去除旧代码中的警告和错误


将老旧的 C语言项目更改为 C++ 项目,目的是方便后期维护,C语言维护成本太高。

零、准备工作

0.1 - 批量修改文件扩展名

Windows 上可以使用命令行 ren 命令,将所有的 .c 文件修改为 .cpp 文件

ren *.c *.cpp

Linux 下可以使用 rename 命令

rename 's/\.c/\.cpp/' *

0.2 - 使用版本控制系统跟踪

整个过程最好使用版本控制系统 如 SVN 和 Git 跟踪,在产生错误时,能够很方便的回退到前一个版本,或者原始版本。

一、常见警告

存在大量的编译警告,会使得一些 warning 问题存在其中不容易被识别或察觉。

1.1 - 字符串字面值


1.1.1 - 问题分析

C语言中字符串字面值 (string literals) 的类型为 char* 类型,而在 C++ 中为 const char* 类型,因此旧代码中很多的字符串字面值 作为参数传递时,使用编译器 g++ 会产生很多警告,尤其是在 Linux 系统下

问题示例

// function declaration 函数声明
void SetComponentStatus(char * comp, int status);

SetComponentStatus("Device_Name", 3);
// 此处会产生警告

警告如下:

warning ISO C++ forbids converting a string constant to 'char *' [-Wwrite-strings]

1.1.2 - 修改方法

  1. 修改函数声明和函数体,将 char* 修改为 const char*
    void SetComponentStatus(const char * comp, int status);
    
  2. 调用处添加 强转 char*

    SetComponentStatus((char*)"Device_Name", 3); // c-style cast
    
  3. 修改编译选项去除 -Wwrite-strings 或添加 -Wno-write-strings

cmake 示例:

set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-write-strings")

最好的方法当然是 1. 但是会耗费很多时间,为了编译时能够减少警告输出方便定位问题,可以酌情选择 3.

1.2 - register 关键字


1.2.1 - 问题分析

register 这个关键字用于请求编译器尽可能的将变量存在CPU内部寄存器中,而不是通过内存寻址访问,以提高效率优化性能。

此关键字在 C++11 弃用,于 C++17 中删除 (Remove Deprecated Use of the register Keyword) , 现在的编译器比我们更知道应该如何优化。

问题代码示例

register int a;

编译报错或警告为:

warning: ISO C++17 does not allow 'register' storage class specifier [-Wregister]

1.2.2 - 修改方法

  1. 直接删除 register 关键字
    int a; // remove register keyword
    
  2. 使用宏隔离,区分 C++ 的使用标准,把 C++17 与 C++17 以下的区分开。
    #if __cplusplus >= 201703L
     int a;
    #else
     register int a;
    #endif
    
  3. 修改编译选项去掉 -Wregister 或添加 -Wno-register

cmake 示例

set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-register")

注:判断 C++版本的宏以及值

标准 __cplusplus 的值
C++ 17 201703L
C++ 14 201402L
C++ 11 201103L

1.2. 同样会面临很大的工作量,可以尝试写脚本批量替换,也会面临隐藏错误的风险,是否可行还要看原来的全量单元测试是否覆盖全面。

二、常见问题

2.1 - 未定义的标识符 extern "C"

引入其他 C语言 方法,使用时会报错,无法解析的外部符号等
C++ 中的编译器为了使用函数重载,声明会编译为区别 C语言编译器的另一种形式

代码示例

extern int AnOldFunction(int a);

void NewFunction()
{
   
    int a = 11;
    // call old function
    AnOldFunction(a); // 此处会报错
}

修改方法

  1. 可以将引入的函数 ,使用 extern "C" 标识
    extern "C" int AnOldFunction(int a);
    
  2. 或者将整个头文件,使用 extern "C" 标识
    extern "C"
    {
         
     #include "OldHeader.h"
    }
    
目录
相关文章
|
9天前
|
C++
C++ 语言异常处理实战:在编程潮流中坚守稳定,开启代码可靠之旅
【8月更文挑战第22天】C++的异常处理机制是确保程序稳定的关键特性。它允许程序在遇到错误时优雅地响应而非直接崩溃。通过`throw`抛出异常,并用`catch`捕获处理,可使程序控制流跳转至错误处理代码。例如,在进行除法运算或文件读取时,若发生除数为零或文件无法打开等错误,则可通过抛出异常并在调用处捕获来妥善处理这些情况。恰当使用异常处理能显著提升程序的健壮性和维护性。
25 2
|
20天前
|
存储 数据可视化 C语言
【C语言】C语言 学生成绩管理系统(源码+报告)【千行代码】【独一无二】
【C语言】C语言 学生成绩管理系统(源码+报告)【千行代码】【独一无二】
|
11天前
|
NoSQL 编译器 程序员
【C语言】揭秘GCC:从平凡到卓越的编译艺术,一场代码与效率的激情碰撞,探索那些不为人知的秘密武器,让你的程序瞬间提速百倍!
【8月更文挑战第20天】GCC,GNU Compiler Collection,是GNU项目中的开源编译器集合,支持C、C++等多种语言。作为C语言程序员的重要工具,GCC具备跨平台性、高度可配置性及丰富的优化选项等特点。通过简单示例,如编译“Hello, GCC!”程序 (`gcc -o hello hello.c`),展示了GCC的基础用法及不同优化级别(`-O0`, `-O1`, `-O3`)对性能的影响。GCC还支持生成调试信息(`-g`),便于使用GDB等工具进行调试。尽管有如Microsoft Visual C++、Clang等竞品,GCC仍因其灵活性和强大的功能被广泛采用。
42 1
|
17天前
|
存储 C语言
【C语言】基础刷题训练4(含全面分析和代码改进示例)
【C语言】基础刷题训练4(含全面分析和代码改进示例)
|
2天前
|
算法框架/工具 C++ Python
根据相机旋转矩阵求解三个轴的旋转角/欧拉角/姿态角 或 旋转矩阵与欧拉角(Euler Angles)之间的相互转换,以及python和C++代码实现
根据相机旋转矩阵求解三个轴的旋转角/欧拉角/姿态角 或 旋转矩阵与欧拉角(Euler Angles)之间的相互转换,以及python和C++代码实现
25 0
|
24天前
|
人工智能 Rust 安全
DARPA计划“消灭”C语言代码
为了加速软件业向内存安全编程语言的过渡,美国国防高级研究计划局(DARPA)正在推动一个名为TRACTOR的人工智能代码转换工具,可自动将遗留C代码转换为Rust,以根治内存安全问题。TRACTOR是TRanslating All C TO Rust的缩写,即“将所有C语言代码转换为Rust语言”。
DARPA计划“消灭”C语言代码
|
9天前
|
程序员 C++ 开发者
C++命名空间揭秘:一招解决全局冲突,让你的代码模块化战斗值飙升!
【8月更文挑战第22天】在C++中,命名空间是解决命名冲突的关键机制,它帮助开发者组织代码并提升可维护性。本文通过一个图形库开发案例,展示了如何利用命名空间避免圆形和矩形类间的命名冲突。通过定义和实现这些类,并在主函数中使用命名空间创建对象及调用方法,我们不仅解决了冲突问题,还提高了代码的模块化程度和组织结构。这为实际项目开发提供了宝贵的参考经验。
23 2
|
9天前
|
C++
拥抱C++面向对象编程,解锁软件开发新境界!从混乱到有序,你的代码也能成为高效能战士!
【8月更文挑战第22天】C++凭借其强大的面向对象编程(OOP)能力,在构建复杂软件系统时不可或缺。OOP通过封装数据和操作这些数据的方法于对象中,提升了代码的模块化、重用性和可扩展性。非OOP方式(过程化编程)下,数据与处理逻辑分离,导致维护困难。而OOP将学生信息及其操作整合到`Student`类中,增强代码的可读性和可维护性。通过示例对比,可以看出OOP使C++代码结构更清晰,特别是在大型项目中,能有效提高开发效率和软件质量。
15 1
|
18天前
|
编译器 Linux C语言
【C++小知识】为什么C语言不支持函数重载,而C++支持
【C++小知识】为什么C语言不支持函数重载,而C++支持
|
23天前
|
存储 编译器 C语言
C++内存管理(区别C语言)深度对比
C++内存管理(区别C语言)深度对比
48 5
下一篇
云函数