【持续更新】C 和 C++ 区别很大!

发布时间 2023-07-22 21:29:38作者: lyazj

一些容易被忽略的 C 与 C++ 的重要区别

头文件

C 标准库头文件名在 C++ 中通常去除扩展名,并加上 c 前缀,如:

  • stdio.h -> cstdio
  • stdlib.h -> cstdlib

其中一个重要的区别是后者保证与 C 库兼容的各个函数名可以在 std 命名空间中找到,但并不保证它们不存在于根命名空间中,这可能会引发一些难以发现的 bug。

/*
 * abs.cpp - 求绝对值的小程序
 *
 * 该代码有一处较为隐蔽的 bug,请尽力找出它!
 */
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <cerrno>

int main(int argc, char *argv[])
{
  if(argc == 1) {  // 校验输入命令行参数
    fprintf(stderr,
        "usage: %s <numbers>\n", program_invocation_short_name);
    exit(EXIT_FAILURE);
  }

  for(int i = 1; i < argc; ++i) {  // 对每个参数,输出运算结果
    char *endp;
    double num = strtod(argv[i], &endp);
    if(*endp) {  // 没有读到字符串结尾,说明出现了错误
      fprintf(stderr, "ERROR: invalid number: %s", argv[i]);
    }
    num = abs(num);  // 计算绝对值
    printf("%lf\n", num);
  }

  return 0;  // 此处始终退回成功值,不是 bug
}

不幸地是,上面的代码顺利通过了编译,且 GCC 发出没有任何警告。

结合输出结果便更容易发现这个 bug!

lyazj@HelloWorld:~$ g++ --version
g++ (Ubuntu 11.3.0-1ubuntu1~22.04.1) 11.3.0
Copyright (C) 2021 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

lyazj@HelloWorld:~$ g++ -Wall -Wshadow -Wextra abs.cpp -o abs
lyazj@HelloWorld:~$ ./abs
usage: abs <numbers>
lyazj@HelloWorld:~$ ./abs 0 1 -1 1.5 -1.5
0.000000
1.000000
1.000000
1.000000
1.000000