摘要:C++扩展名选用.cxx而非.cpp,源于Unix历史:cpp命令早被C预处理器占用,为避免冲突衍生出.cxx、.cc等变体。mongocxx遵循这一传统,体现了C++生态的历史传承。现代项目虽多用.cpp,但.cxx仍是老牌库的常见选择,构建工具均能妥善支持。
为什么C++项目偏爱.cxx扩展名:从MongoDB驱动说起
一个令人困惑的发现
当你第一次接触MongoDB的C++驱动时,可能会感到疑惑:为什么它叫mongocxx而不是更直观的mongocpp?这背后其实隐藏着C++发展史上的一段有趣故事。
罪魁祸首:被占用的cpp命令
Unix系统的历史遗产
在Unix/Linux系统中,cpp这个命令名早在上世纪70年代就被C预处理器(C Preprocessor)占据了:
bash
$ which cpp
/usr/bin/cpp
$ cpp --version
cpp (GCC) 9.3.0
Copyright © 2020 Free Software Foundation, Inc.
命名冲突的现实困境
如果C++编译器也命名为cpp,会导致严重混乱:
bash
# 假设两个命令都叫cpp,会发生什么?
cpp my_program.cpp # 这是调用预处理器还是编译器?
这种冲突在构建工具和Makefile中尤为明显,系统无法区分你到底要调用哪个工具。
C++扩展名的"战国时代"
为了避免与预处理器冲突,C++社区出现了多种文件扩展名:
各派系之争
cpp
// 1. .cpp 派 (现在的主流)
#include <iostream>
// 多数现代IDE和构建系统首选
// 2. .cxx 派 (mongocxx的选择)
#include <mongocxx/client.hpp>
// 常见于老牌项目和Unix传统
// 3. .cc 派 (Google风格)
#include "base/logging.h"
// Google内部代码规范要求
// 4. 其他变体
file.C // 区分大小写的系统
file.c++ // 较少使用
编译器的兼容性
各大编译器都对各种扩展名提供了支持:
bash
g++ -c file.cxx # 编译.cxx文件
g++ -c file.cc # 编译.cc文件
clang++ -c file.cpp # 编译.cpp文件
mongocxx的命名逻辑
保持历史一致性
MongoDB驱动遵循了传统的命名规范:
scss
mongoc → C语言驱动 (基础层)
└── mongocxx → C++驱动 (基于C驱动的封装)
项目结构体现
bash
mongocxx/
├── src/mongocxx/ # C++头文件使用.hpp
│ └── client.hpp
├── test/ # 测试代码可能使用.cxx
│ └── test_client.cxx
└── CMakeLists.txt # 构建配置处理各种扩展名
现代开发中的现状
现状分析
虽然.cpp已成为事实上的主流标准,但很多历史悠久的项目仍然保持传统:
| 项目类型 | 常用扩展名 | 说明 |
|---|---|---|
| 新启动项目 | .cpp | 现代IDE和构建系统友好 |
| 老牌库项目 | .cxx/.cc | 保持历史一致性 |
| Google相关 | .cc | 遵循内部代码规范 |
构建系统的适应性
现代构建系统都能正确处理各种扩展名:
cmake
# CMake自动识别所有C++扩展名
add_library(mongocxx
src/file1.cxx
src/file2.cpp
src/file3.cc
)
# 或者明确指定
set(CMAKE_CXX_EXTENSIONS .cxx .cpp .cc)
实践建议
对于新项目
bash
# 推荐使用.cpp,因为:
# 1. 更广泛的工具支持
# 2. 更直观的命名
# 3. 社区主流选择
my_program.cpp
理解老项目
当你遇到.cxx扩展名时,现在应该明白:
- 这不是标新立异,而是历史传承
- 不影响代码功能和性能
- 构建工具都能正常处理
结语
mongocxx的命名选择反映了C++语言的演进历史。从今天的视角看,.cxx可能显得有些"老派",但它承载了C++从Unix实验室走向全世界的完整历程。
这种命名上的多样性,恰恰体现了C++生态的丰富性和兼容性------无论是现代的.cpp还是传统的.cxx,都能在同一个项目中和谐共存,共同构建强大的软件系统。
所以下次看到.cxx扩展名时,你不必困惑,只需会心一笑:这是一个经历过C++"战国时代"的老兵。