C/C++编程:宏__cplusplus

1059 篇文章 278 订阅

处于一些不可抗力,历史原因,我们不得不在C++中使用一些C语言代码,比如Linux 系统调用。在现代C++出现之前,大部分人当谈到“C与C++的区别是什么”时,普遍除了回答面向对象的类特性、泛型编程的模板特性之外,就没有其他看法了,甚至直接回答差不多。 这当然是错误的,C++并不是C的一个超集,如下图大致回答了C和C++相关的兼容情况:
在这里插入图片描述
在编写 C++ 时,也应该尽可能
的避免使用诸如void* 之类的程序风格。而在不得不使用 C 时,应该注意使用 extern "C" 这种特性,将 C 语言的代码与 C++ 代码进行分离编译,再统一链接这种做法
,例如:

// foo.h
#ifdef __cplusplus
extern "C" {
#endif

int add(int x, int y);

#ifdef __cplusplus
}
#endif
// foo.c
int add(int x, int y) {
	return x+y;
}
// 1.1.cpp
#include "foo.h"
#include <iostream>
#include <functional>

int main() {
	[out = std::ref(std::cout << "Result from C code: " << add(1, 2))](){
	out.get() << ".\n";
	}();
	return 0;
}

应先使用 gcc 编译 C 语言的代码:

gcc -c foo.c

编译出 foo.o 文件,再使用 clang++ 将 C++ 代码和 .o 文件链接起来(或者都编译为 .o 再统一
链接):

clang++ 1.1.cpp foo.o -std=c++2a -o 1.1

当然,你可以使用 Makefile 来编译上面的代码:

C = gcc

CXX = clang++

SOURCE_C = foo.c
OBJECTS_C = foo.o

SOURCE_CXX = 1.1.cpp

TARGET = 1.1
LDFLAGS_COMMON = -std=c++2a

all:
	$(C) -c $(SOURCE_C)
	$(CXX) $(SOURCE_CXX) $(OBJECTS_C) $(LDFLAGS_COMMON) -o $(TARGET)
clean:
	rm -rf *.o $(TARGET)

注意:Makefile 中的缩进是制表符而不是空格符,如果你直接复制这段代码到你的编辑器中,制表符可能会被自动替换掉,请自行确保在 Makefile 中的缩进是由制表符完成的。

现在,我们来完整理解一下这个头文件:

// foo.h
#ifdef __cplusplus
extern "C" {
#endif

// *** 一些代码 *** 

#ifdef __cplusplus
}
#endif

这种类型的头文件可以被#include到C和C++文件中进行编译。由于extern "C"可以抑制C++对函数名、变量名等符号进行名称重整,因此编译出的C目标文件和C++目标文件中的变量、函数名称等符号都是相同的(否则不相同),链接器可以可靠的对两种类型的目标文件进行链接。

__cplusplus宏通常被定义为一个整型值(比以往标准中更大的值)。如C++03中__cplusplus199711L,C++11中被定义为201103L。如果想确定支持C++11编译器进行编译时,那么可以按照如下方法进行检测:

#if __cpluscplue < 201103L
	#error "should use c++11 implementation"
#endif

上面用了预处理指令#error,这就使得不支持C++11的代码编译立即报错并终止编译。

other:

可以通过预处理指令#if#error配合,使得在预处理阶段进行断言。比如:

#ifndef _COMPLEX_H
#error "Never use <bits/cmathcalls.h>" directly; include <complex.h> instead
#endif

如果程序员直接包含<bits/cmathcalls.h>进行编译就会引发错误,#error指令会将后面的语句输出,提醒用<complex.h>而不是 <bits/cmathcalls.h>。这样,通过预处理的断言,库发布者就可以避免一些头文件的引用问题

面试题: 如何判断程序是C程序还是CPP程序

#include <iostream>
using namespace std;
 
int main()
{
#ifdef __cplusplus
	cout << "c++" << endl;
#else
	cout << endl;
#endif
}

进一步阅读的参考文件(待完成)

在这里插入图片描述

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值