1. 概念对比:JavaScript编译时 vs C++预处理
JS/TS 编译时处理
javascript
// 1. 模块打包时的条件编译
if (process.env.NODE_ENV === 'development') {
console.log('开发模式');
}
// 2. TypeScript 条件类型
type ApiResponse<T> = T extends string ? string[] : T[];
// 3. Webpack DefinePlugin
const API_URL = __API_URL__; // 编译时替换
// 4. 模块导入路径解析
import utils from '@/utils'; // @ 符号会被编译器处理
C++ 预处理器
cpp
// 1. 条件编译
#ifdef DEBUG
std::cout << "调试模式" << std::endl;
#endif
// 2. 宏定义
#define MAX(a, b) ((a) > (b) ? (a) : (b))
// 3. 常量定义
#define API_URL "https://api.example.com"
// 4. 文件包含
#include <iostream> // 预处理器会插入整个文件内容
2. 预处理器指令
2.1 文件包含 #include
(类似 import)
cpp
// 系统头文件 - 使用尖括号
#include <iostream> // 从系统标准库搜索
#include <vector> // 编译器预定义路径
#include <string>
// 用户头文件 - 使用双引号
#include "MyClass.hpp" // 从当前目录搜索
#include "utils/helper.hpp" // 相对路径
#include "../common/base.hpp" // 父目录
// ThreePP 项目示例
#include "threepp/threepp.hpp"
#include "threepp/cameras/PerspectiveCamera.hpp"
与JavaScript对比:
javascript
// JavaScript - 运行时动态加载
import { useState } from 'react'; // ← 模块系统
import MyComponent from './MyComponent'; // ← 相对路径
import utils from '@/utils'; // ← 路径别名
// C++ - 编译时文本替换
#include <iostream> // ← 预处理器直接插入文件内容
#include "MyClass.hpp" // ← 文本级别的复制粘贴
2.2 宏定义 #define
(类似常量和函数)
简单常量宏
cpp
// 数值常量
#define PI 3.14159
#define MAX_SIZE 1000
#define VERSION "1.0.0"
// 使用
double area = PI * radius * radius;
int buffer[MAX_SIZE];
std::cout << "版本: " << VERSION << std::endl;
JavaScript对比:
javascript
// JavaScript
const PI = 3.14159;
const MAX_SIZE = 1000;
const VERSION = "1.0.0";
// 或者使用 enum
enum Config {
MAX_SIZE = 1000
}
函数式宏 (类似JavaScript函数)
cpp
// 简单函数宏
#define MAX(a, b) ((a) > (b) ? (a) : (b))
#define MIN(a, b) ((a) < (b) ? (a) : (b))
#define SQUARE(x) ((x) * (x))
// 多行宏 - 使用反斜杠续行
#define DEBUG_PRINT(var) \
std::cout << #var << " = " << var << std::endl
// 使用示例
int result = MAX(10, 20); // 展开为: ((10) > (20) ? (10) : (20))
int sq = SQUARE(5); // 展开为: ((5) * (5))
DEBUG_PRINT(result); // 输出: result = 20
JavaScript对比:
javascript
// JavaScript - 真正的函数
const MAX = (a, b) => a > b ? a : b;
const MIN = (a, b) => a < b ? a : b;
const SQUARE = x => x * x;
// 模板字符串类似功能
const debugPrint = (name, value) => console.log(`${name} = ${value}`);
2.3 条件编译 (类似 if...else)
基础条件编译
cpp
// 调试版本 vs 发布版本
#ifdef DEBUG
#define LOG(msg) std::cout << "[DEBUG] " << msg << std::endl
#else
#define LOG(msg) // 空宏,发布版本不输出
#endif
// 平台特定代码
#ifdef _WIN32
#include <windows.h>
#define SLEEP(ms) Sleep(ms)
#elif defined(__linux__)
#include <unistd.h>
#define SLEEP(ms) usleep(ms * 1000)
#elif defined(__APPLE__)
#include <unistd.h>
#define SLEEP(ms) usleep(ms * 1000)
#endif
JavaScript对比:
javascript
// JavaScript - 运行时条件
if (process.env.NODE_ENV === 'development') {
console.log('[DEBUG]', msg);
}
// Webpack DefinePlugin 编译时替换
if (__DEV__) { // 编译时会被替换为 true 或 false
console.log('[DEBUG]', msg);
}
复杂条件编译
cpp
// 检查编译器特性
#if __cplusplus >= 201703L // C++17或更高
#include <optional>
using optional_int = std::optional<int>;
#else
// 自定义optional实现
#include "my_optional.hpp"
using optional_int = my_optional<int>;
#endif
// 检查宏是否定义
#ifndef BUFFER_SIZE
#define BUFFER_SIZE 1024 // 如果没有定义,则使用默认值
#endif
// 多条件判断
#if defined(USE_OPENGL) && !defined(USE_VULKAN)
#include "opengl_renderer.hpp"
using Renderer = OpenGLRenderer;
#elif defined(USE_VULKAN)
#include "vulkan_renderer.hpp"
using Renderer = VulkanRenderer;
#else
#error "Must define either USE_OPENGL or USE_VULKAN"
#endif
2.4 预定义宏 (类似全局变量)
cpp
#include <iostream>
int main() {
// 文件信息
std::cout << "文件: " << __FILE__ << std::endl;
std::cout << "行号: " << __LINE__ << std::endl;
std::cout << "函数: " << __FUNCTION__ << std::endl;
// 编译信息
std::cout << "编译日期: " << __DATE__ << std::endl;
std::cout << "编译时间: " << __TIME__ << std::endl;
// C++标准版本
std::cout << "C++版本: " << __cplusplus << std::endl;
// 编译器信息
#ifdef _MSC_VER
std::cout << "编译器: MSVC " << _MSC_VER << std::endl;
#elif defined(__GNUC__)
std::cout << "编译器: GCC " << __GNUC__ << "." << __GNUC_MINOR__ << std::endl;
#elif defined(__clang__)
std::cout << "编译器: Clang " << __clang_major__ << "." << __clang_minor__ << std::endl;
#endif
return 0;
}
JavaScript对比:
javascript
// JavaScript - 运行时信息
console.log('文件:', import.meta.url); // ES modules
console.log('Node版本:', process.version);
console.log('平台:', process.platform);
// 编译时信息(需要构建工具支持)
console.log('构建时间:', __BUILD_TIME__);
console.log('版本:', process.env.npm_package_version);