【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"
    }
    
目录
相关文章
|
12天前
|
C++ Windows
应用程序无法正常启动(0xc0000005)?C++报错0xC0000005如何解决?使命召唤17频频出现闪退,错误代码0xC0000005(0x0)
简介: 本文介绍了Windows应用程序出现错误代码0xc0000005的解决方法,该错误多由C++运行库配置不一致或内存访问越界引起。提供包括统一运行库配置、调试排查及安装Visual C++运行库等解决方案,并附有修复工具下载链接。
499 1
|
2月前
|
安全 C语言 C++
比较C++的内存分配与管理方式new/delete与C语言中的malloc/realloc/calloc/free。
在实用性方面,C++的内存管理方式提供了面向对象的特性,它是处理构造和析构、需要类型安全和异常处理的首选方案。而C语言的内存管理函数适用于简单的内存分配,例如分配原始内存块或复杂性较低的数据结构,没有构造和析构的要求。当从C迁移到C++,或在C++中使用C代码时,了解两种内存管理方式的差异非常重要。
127 26
|
7月前
|
存储 安全 C语言
C++ String揭秘:写高效代码的关键
在C++编程中,字符串操作是不可避免的一部分。从简单的字符串拼接到复杂的文本处理,C++的string类为开发者提供了一种更高效、灵活且安全的方式来管理和操作字符串。本文将从基础操作入手,逐步揭开C++ string类的奥秘,帮助你深入理解其内部机制,并学会如何在实际开发中充分发挥其性能和优势。
|
4月前
|
监控 算法 数据处理
基于 C++ 的 KD 树算法在监控局域网屏幕中的理论剖析与工程实践研究
本文探讨了KD树在局域网屏幕监控中的应用,通过C++实现其构建与查询功能,显著提升多维数据处理效率。KD树作为一种二叉空间划分结构,适用于屏幕图像特征匹配、异常画面检测及数据压缩传输优化等场景。相比传统方法,基于KD树的方案检索效率提升2-3个数量级,但高维数据退化和动态更新等问题仍需进一步研究。未来可通过融合其他数据结构、引入深度学习及开发增量式更新算法等方式优化性能。
142 17
|
2月前
|
API 数据安全/隐私保护 C++
永久修改机器码工具, exe一机一码破解工具,软件机器码一键修改工具【c++代码】
程序实现了完整的机器码修改功能,包含进程查找、内存扫描、模式匹配和修改操作。代码使用
|
10月前
|
存储 安全 数据管理
C语言之考勤模拟系统平台(千行代码)
C语言之考勤模拟系统平台(千行代码)
178 4
|
3月前
|
C++
爱心代码 C++
这段C++代码使用EasyX图形库生成动态爱心图案。程序通过数学公式绘制爱心形状,并以帧动画形式呈现渐变效果。运行时需安装EasyX库,教程链接:http://【EasyX图形库的安装和使用】https://www.bilibili.com/video/BV1Xv4y1p7z1。代码中定义了屏幕尺寸、颜色数组等参数,利用随机数与数学函数生成动态点位,模拟爱心扩散与收缩动画,最终实现流畅的视觉效果。
290 0
|
9月前
|
存储 算法 程序员
C 语言递归算法:以简洁代码驾驭复杂逻辑
C语言递归算法简介:通过简洁的代码实现复杂的逻辑处理,递归函数自我调用解决分层问题,高效而优雅。适用于树形结构遍历、数学计算等领域。
|
10月前
|
并行计算 算法 测试技术
C语言因高效灵活被广泛应用于软件开发。本文探讨了优化C语言程序性能的策略,涵盖算法优化、代码结构优化、内存管理优化、编译器优化、数据结构优化、并行计算优化及性能测试与分析七个方面
C语言因高效灵活被广泛应用于软件开发。本文探讨了优化C语言程序性能的策略,涵盖算法优化、代码结构优化、内存管理优化、编译器优化、数据结构优化、并行计算优化及性能测试与分析七个方面,旨在通过综合策略提升程序性能,满足实际需求。
263 1