我应该停止使用术语C / C ++吗?


140

我了解C和C ++是不同的语言,但是当我学习C ++时,总是被告知C是C ++的子集,或者C ++是带有类的C。在C ++ x0,C ++ 11(或现代的C ++ 11/14/17)问世之前,这都是事实。实际上(特别是在嵌入式系统上工作时),很可能会发现用C ++编写的代码,但是很多部分完全是用纯C语言编写的。这里我有几个问题:

  1. 我应该停止使用术语C / C ++吗?
  2. 如果对#1的回答是肯定的,那么我将如何调用混合使用C和C ++的程序?
  3. 鉴于这两种语言都是“不同的”语言,C ++编译器很可能在某些时候停止支持用C语言编写的代码(因为现代c ++在指针,动态内存处理等基本内容上与C思维方式有所出入)
  4. 现在制定C / C ++标准的人员之间是否存在任何协作以保持兼容性
  5. 如果#4是肯定的,那么这种合作可能会在不久的将来随着现代c ++的出现而结束(11/14/17)

我知道已经有类似的问题,但是我敢肯定,很多人都会分享这些问题,因此我非常有兴趣获得良好的答案,尤其是在不久的将来与C ++趋势有关的观点。


35
直到出现C ++ x0,C ++ 11否,C89都不是C ++ 98的子集时,这才是真的

35
Should I stop using the term C/C++。是。这仅由招聘人员和人力资源部使用。工程师将使用该术语C或将其C++用作独立语言。如果您发现有一个混用术语的工程师,请避免使用它们。
马丁·约克

8
@LokiAstari:真的吗?我猜SQLite开发人员是人事,因为他们没有空缺职位。这是一个令人难以置信的局限性观点(请与您情况中的其他人一样,拒绝我的回答)。

4
@greyfade:很难假设任何地方的任何人都可以声明一个常见的字符序列。“ C / C ++”可能是为某种特定语言选择的名称,但这并不意味着“ C / C ++”的使用指的是该语言,这比我复制该网站并用“ C / C ++”替换“ C / C ++”更重要。关于C ++标准草案的所有讨论都会突然使用错误的术语“ C ++ 1z”。简而言之,字符串“ C / C ++”从未引用过名为“ C / C ++”的笑话语言,也从未如此。
Ben Voigt

32
@TomDworzanski,stroustrup.com/bs_faq.html# C-is- subset “从严格的数学意义上讲,C并不是C ++的子集...但是,C ++支持C支持的所有编程技术...不是很少能在几小时内将成千上万行C转换为C样式的C ++,因此,C ++是ANSI C的超集,而ANSI C是K&R C的超集,而ISO C ++是1985年,C ++成为C ++的超集。写得好的C也往往是合法的C ++。例如,Kernighan&Ritchie中的每个示例:“ C编程语言(第二版)”也是C ++程序。

Answers:


183

C从来不是C ++的子集。最明显的例子是int new;。自从C89和C ++ 98以来,情况就是如此,随着新标准的出现,这些语言之间的距离仅在进一步的增长。

我应该停止使用术语C / C ++吗?

如果对#1的回答是肯定的,那么我将如何调用混合使用C和C ++的程序?

源文件以一种或另一种语言编写。一个程序可以包括来自多种语言的代码,这些代码可以一起工作,也可以包含通过链接不同的编译对象而生成的可执行文件。您可能会说程序是用C和C ++编写的,“ C / C ++”不是一种语言。

鉴于这两种语言都是“不同”的语言,那么C ++编译器是否有可能在某些时候停止支持用C语言编写的代码

3)他们从来没有做过。char *a = malloc(10);CC ++至少从没有ISO标准开始就没有完全兼容(我不知道有关预标准化日期的所有详细信息)。单击链接或查看以下文件,该文件适用于C89及更高版本,但在任何C ++标准下均无效。

4)afaik不,工作组彼此了解,但是标准会做出最适合自己的决定。

/* A bunch of code that compiles and runs under C89 but fails under any C++ */

/* type aliases and struct names occupy separate namespaces in C, not in C++ */
struct S { int i; };
typedef int S;


struct Outer { struct Inner { int i; } in; };
/* struct Inner will be Outer::Inner in C++ due to name scope */
struct Inner inner;


/* default return type of int in C, C++ functions need explicit return types */
g() {
    return 0;
}


/* C sees this as two declarations of the same integer,
 * C++ sees it as redefinition */
int n;
int n;


/* K&R style argument type declarations */
void h(i) int i; { }


/* struct type declaration in return type */
struct S2{int a;} j(void) { struct S2 s = {1}; return s; }


/* struct type declaration in argument, stupid and useless, but valid */
/*void dumb(struct S3{int a;} s) { } */


/* enum/int assignment */
enum E{A, B};
enum E e = 1;


void k() {
    goto label; /* C allows jumping past an initialization */
    {
        int x = 0;
label:
        x = 1;
    }
}


/* () in declaration means unspecified number of arguments in C, the definition
 * can take any number of arguments,
 * but means the same as (void) in C++  (definition below main) */
void f();

int main(void) {
    f(1); /* doesn't match declaration in C++ */
    {
        /* new is a keyword in C++ */
        int new = 0;
    }

    /* no stdio.h include results in implicit definiton in C.  However,
     * as long as a matching function is found at link-time, it's fine.
     * C++ requires a declaration for all called functions */
    puts("C is not C++");
    {
        int *ip;
        void *vp = 0;
        ip = vp; /* cast required in C++, not in C */
    }
    return 0;
}

/* matches declaration in C, not in C++ */
void f(int i) { }

我总是觉得值得一提的是C Objective-C的子集。


59
Objective-C被专门设计为C 的严格超集,没有冲突的语法和完全正交的对象系统。这是一个极端的选择,您实际上可以使用“ Objective-C”的“ Objective”部分并将其附加到其他语言上,从而创建例如Objective-MODULA-2。最著名的是Apple的Objective-C ++,它具有两个完全正交,非交互,非集成的对象系统。
约尔格W¯¯米塔格

20
@masonwheeler,如果OP要查看C的实际超集是什么样子。
xhainingx

26
“源文件是用一种或另一种语言编写的。” 告诉我的程序,它可以干净地编译为标准C99和C ++ 89。两种语言都不是另一种语言的子集,但是两种语言的交集被广泛地作为目标。参见Lua等。
2015年

28
@munificent我可以编写也可以运行的C ++代码javac,但这有什么意义呢?
xhainingx 2015年

22
@munificent一个可以用三种语言(C,/ bin / sh和f77)编译的程序的示例是IOCCC 1986的applin.c条目。根据您的定义,该标记C/Fortran/sh现在有意义吗? ioccc.org/years-spoiler.html#1986
2015年

108

是一个原因,这些条款走到一起经常。尽管您不应该告诉C老师他的语言是C ++的子集,但这里有一些道理。其他人已经暴露了您老师的观点。这非常好(并通过示例等进行了说明)。但是我们不住在象牙塔或书本中。

您的上司不会在乎您使用的确切语言。如果他对编程有所了解,只需告诉他您使用过C / C ++,这听起来就像“我使用了一种需要编译为带有DLL和所有复杂内容的机器代码的语言”。这是“外部沟通”部分。

如果您创建一个可以同时使用C和C ++进行接口的库,则肯定要将其称为C / C ++库。当然,有人会举起手来,问您为什么不将它称为恰好具有C ++包装器的C库,反正C ++可以链接到C库,因此您根本不需要提及它。只需回答:“是的,您是对的,这是一个C / C ++库”。这是“内部沟通”部分。

如果您为C ++创建一个词法分析器,您会惊讶于它与C一起工作得很好。您甚至可能不需要全部修改。这就是“如果它看起来像鸭子等”。部分。

等等。

我见过的大多数C程序都可以作为C ++代码进行修改(并且可以正常工作)而无需进行修改。不要让一些例外情况或教条主义(但是有影响力的)程序员愚弄您的直觉。C和C ++ 如此紧密,并且经常兼容,并且经常混合和匹配在一起,以至于使用了术语C / C ++。之所以使用它,是因为它对描述这种情况非常有用,只要您使用的不是Java或PHP,无论您考虑使用C还是C ++,这些情况都没有关系。我们知道这是“错误的”,但是我们不在乎,它比错误更有用。

它可能会被滥用,可能是愚蠢的,但是,我仍然不确定通过比所需的方法更加学究并且拒绝以他人理解的方式进行交流会获得什么好处。如果您在某些特定情况下感到不舒服,则不要使用通用术语C / C ++,而要使用与情况相关的术语(C或C ++)。

不要害怕未来。我们的操作系统是用C编写的。当前许多C / C ++软件生产都使用C ++。这对夫妇在这里住了一段时间。没有人会对一个变得与另一个不兼容感兴趣(实际上,反之亦然)。

要具体说明您的观点:

1)视情况而定。是的,当它可能导致混乱,感到不安,或者仅仅是错误或不合上下文时。当您认为足够时不行。

2)不适用

3)我认为没有,但是我没有水晶球。

4)不知道

5)我认为没有朝这个方向推进的想法


7
评论已删除,因为它们越来越吵。
克里斯·

3
为什么这么多投票?它充满了不准确和虚假的主张!
Zaibis 2015年

5
@Zaibis您是否足够友善地解释哪些主张是虚假或不正确的?
号码2015年

3
按照您的逻辑,C / C ++ / Objective-C / Fortran / Pascal应该是有效的表达式,但这听起来很愚蠢。术语C / C ++的问题在于它可能意味着几件事,因此您无法保证它会符合所需的含义。在我的实践中,人们通常将其理解为“ C只是C ++的原始版本”,这是错误的。
martinkunev 2015年

4
除了该术语的固有有效性之外,C/C++还不是一个明确的术语,因此没有用。在您的示例之后,a C/C++ library可能意味着带有C ++包装器的C库,或者带有C包装器的C ++库。或可能意味着该库由几个模块组成,一些模块使用C ++编译,某些模块用C编译。这一点一点也不明确。对我来说,说一个内置的图书馆C and C++要清晰得多,或者说C library with compatibility with C++也要清晰得多。而这里的歧义只有两种,想像一下使用这种“交流策略”
来做

43

与之相反,我会说这取决于上下文

当说“这是一个C / C ++程序”之类的东西时,术语“ C / C ++”通常不合适,但是已经在其他答案中进行了深入探讨。

但是,在某些情况下C / C ++可能适用。

  • 通常有多种库都具有C和C ++ API。我想,如果您将这样的事情称为C / C ++库,这与事实相差不远。我们人类喜欢压缩信息,所以说“ opencv是一个C / C ++库”是简短,清晰且易于理解的,与说“ opencv是一个库,它带有C和C ++的标头”相比较。
  • 您可以谈论语言设计和语法。从语言语法的角度来看,您可能会说一种语言具有类似C / C ++的语法。
  • 您组织一次编码竞赛,并且接受用C和C ++编写的解决方案
  • 您正在雇用新的程序员,并且大多数任务将是C或C ++,因此,程序员应该会同时使用这两种语言。在嵌入式开发中很常见,其中C更适合某些(通常非常小的)微控制器,而C ++更适合于其他微控制器。在这种情况下,您可能会说您正在寻找C / C ++程序员。

10
我认为这与P.SO上的普遍共识背道而驰。(在这里,您必须对看起来像“敏捷/炒作/像唯一和正确的事物”一样的事物进行投票,对其余的事物进行投票)像往常一样受到欢迎。伙计们,编程不是一种信仰,而且这个网站也不是一本神圣的书。

16
最后一颗子弹点实际上展示了一个重大问题:您是否正在寻找(1)一个人说的已知,无论是 C或C ++,(2),知道的人 C和C ++或(3)一个人是迷茫听到这些都是不同语言。不要帮助第三个池增长。
5gon12eder 2015年

10
如果您真正要寻找的是最后一个要点,最好用“具有C和C ++经验的程序员”表示。标题为“程序员”的求职者广告,根据需要的经验列出了“ C和C ++”或“ C或C ++”,与标题为“程序员”的人并没有明显不同,并列出了“ C / C ++”作为必要的资格,但这是很多更准确。您正在寻找这种工作的人类型可能会非常欣赏这种表达的准确性。
CVn 2015年

10
在书面语言中,“ /”通常被解释为逻辑or,而不是逻辑xor。因此,它要么是其中之一,要么是两者兼有。在工作清单中,您知道C或C ++或两者。现在,我觉得很多人都对该词保持虔诚。一个好的 C程序员可以很好地选择C ++,而不必考虑两种语言的不同。我开始编写PHP代码,然后转到Scala(两种完全不同的语言),为什么C程序员不能使用C ++,反之亦然?如果在正确的上下文中使用C / C ++术语,则具有一定的优势。
ILikeTacos 2015年

4
您也可以使用C / C ++来描述旨在以C或C ++形式编译的程序,或者具有单独的C和C ++组件的程序。
immibis 2015年

30

通常,SO用户要求提出问题的人选择一种语言:C或C ++。为什么?

C和C ++之间有许多细微的区别。例如,在C ++中,const除非声明extern,否则全局范围的变量具有内部链接,而在C中,除非声明,否则其具有外部链接static。通过说“ C / C ++”,OP宣称知道他们的问题的答案在C和C ++中都是相同的,而实际上可能不是。这不必要地使想要回答的人变得更加困难。

  • 有时,我们可以发现该代码在一种或另一种语言中无效(例如,从C void*到指针的隐式转换在C ++中是无效的)。真烦人 当您拥有一段在C中有效但在C ++中无效的代码时,为什么要说“ C / C ++”?您打算使用C,还是这只是打算使用C ++的代码中的错误?

  • 有时,根据语言的不同,答案也会有所不同(例如,C99中存在可变长度数组,而C ++中不存在)。如果我们不知道您在说什么语言,要么必须猜测,要么在只有一种实际有用的情况下为两种情况都写一个答案,因为您知道您实际上在使用哪种语言。你只是不告诉我们!

  • 有时,两种语言的答案实际上是相同的,但是很难确定。例如,我认为C和C ++具有相同的整数转换规则,但是为了真正确定,我必须仔细阅读这两个标准。同样,当您可能只在乎一种语言时,这使我的工作量增加了两倍。

无论如何,要回答您的其他问题:

  1. 是。

  2. 如果将C和C ++代码链接在一起,则可以同时使用两个标签,但是请指定每个文件使用的语言。

  3. 有时会有重大更改,但它们很少见,而且影响力通常有限(否则,它们不会获得批准)。例如,auto在C ++ 11中。

  4. 我不认为他们直接合作,但他们关注另一种语言的发展,并尝试避免引入会使兼容性变得更加困难的更改。

如果您确实想了解两种语言,那很好,您可以在问题中说出来。当您说“ C / C ++”时,我真的不确定您的意思,而且看起来您好像正在对这两种语言进行假设。


7
我知道有人在C和C ++的交集中编写代码,并使用C ++编译器进行类型检查,但使用C编译器进行代码生成。不过,我不知道这是否真的有意义。但是,这是每两年在Linux内核邮件列表中出现的一个话题,当时有人提交了一个补丁以将(在Linux内核的统一对象导向的驱动程序模型中非常重要)重命名为struct class类似struct klass的名称,并且然后总是被莱纳斯击落。
约尔格W¯¯米塔格

3
@JörgWMittag:我从未见过有人使用“ C / C ++”作为“ C和C ++的通用子集”的简写,并且也知道他在说什么。故意在公共子集中工作的人倾向于通过不缩写来使之明确。
Bart van Ingen Schenau

2
特别是有关在Stack Exchange问​​题中使用C / C ++的问题,这是一个很好的答案,而不是一般而言。
immibis 2015年

@BartvanIngenSchenau您遇到了几个性病委员会成员?
curiousguy

18

我总是被告知C是C ++的子集,或者C ++是带有类的C。直到出现C ++ x0,C ++ 11(或一般来说是现代的C ++ 11/14/17)之前,这都是安静的事实。

C从来不是C ++的子集。例如,C89不是C ++ 98的子集。

一些例子:

  • C ++不支持函数参数声明的C89 标识符列表形式
  • C89和C ++ 98的字符常量类型不同
  • C89和C ++ 98的字符串文字类型不同
  • 逻辑运算符在C89和C ++ 98中产生不同的类型(intvs bool
  1. 我应该停止使用术语C / C ++吗?

是。

  1. 如果对#1的回答是肯定的,那么我将如何调用混合使用C和C ++的程序?

程序可以是C或C ++(如果即使某些非常基本的程序也可以使用C或C ++编译器进行编译)。您使用什么编译器进行编译?它应该回答您的问题。Harbison&Steele创造了术语Clean C来表示C和C ++的一个常见子集,但我认为这不是一个好主意。

编辑:但是我承认,从技术上讲,您可以在单个程序中链接C和C ++对象文件,但是OTH允许在单个程序中混合使用多种语言,例如Java和C ++。我认为使用术语C / C ++程序只会使人们更加困惑,因为它是用一种称为C / C ++的单一语言编写的。

  1. 鉴于这两种语言都是“不同的”语言,C ++编译器很可能在某些时候停止支持用C语言编写的代码(因为现代c ++在指针,动态内存处理等基本内容上与C思维方式有所出入)

_GenericC99或C11具有许多C ++版本不支持的功能(例如:可变长度数组,灵活数组成员等)。


关于多语言程序:广泛使用JNI的程序可以称为C / Java程序。两种语言一起使用的事实并不意味着它们是一起编译的。
immibis 2015年

1
stroustrup.com/bs_faq.html#C-is-subset “从严格的数学意义上讲,C并不是C ++的子集...但是,C ++支持C支持的所有编程技术...能够在数小时内将成千上万行C转换为C样式的C ++,因此,C ++是ANSI C的超集,就像ANSI C是K&R C的超集一样,而ISO C ++是C ++的超集就像它存在于1985年一样。写得很好的C也往往是合法的C ++。例如,Kernighan&Ritchie中的每个示例:“ The C Programming Language(第二版)”也是C ++程序。

@Ben“ C编程语言(第二版)”中的第一个程序(hello world)忽略了main的返回类型,该返回类型在C ++中无效。
2015年

1
@ouah,看来Stroustrup教授当时错过了一个:-)注意C11也不允许:-)但是,可以肯定的是,在早期版本的C ++中是不允许的。

4
@ouah,那不是C ++的第一个版本。这本书来自1988年,当时两种语言都不是ISO标准。当时的C ++当前版本是Bjarne Stroustrup于1985年撰写的书。
2015年

17

有些程序是用C和C ++混合编写的

这只是生活中的事实。您可以从C和C ++编译目标文件并将它们链接在一起。结果可以相当合理地称为“ C / C ++程序”。

但这仅仅是整个程序。各个编译单元如何?

有C的子集,也有C ++的子集

在该子集中编写的程序(或编译单元)将在兼容的C和C ++编译器下进行编译并以相同的方式运行。这样的程序或文件可以正确地称为“ C / C ++程序”或“ C / C ++文件”。

诸如头文件之类的部分程序也可以在C和C ++程序中使用。这样的头文件可以正确地称为C / C ++头。

引用Bjarne Stroustrup教授的话:

C是C ++的子集吗?

从严格的数学意义上讲,C不是C ++的子集。有些程序是有效的C,但不是有效的C ++,甚至有几种编写在C和C ++中具有不同含义的代码。但是,C ++支持C支持的所有编程技术。每个C程序都可以用相同的方式在C ++中以相同的运行时和空间效率来编写。能够在数小时内将成千上万行ANSI C转换为C样式C ++并不少见。因此,C ++是ANSI C的超集,就像ANSI C是K&R C的超集一样,而ISO C ++则是1985年存在的C ++的超集。

编写良好的C往往也合法C ++。例如,Kernighan&Ritchie中的每个示例:“ C编程语言(第二版)”也是C ++程序。

所以是的,有C / C ++之类的东西。这既是有效的C也是有效的C ++。

C预处理器是C语言的一部分。C ++预处理器是C ++语言的一部分

您可以编写一个将在C或C ++下进行编译且不同的编译单元。例如,它可能具有用C编译的基本功能,但如果用C ++编译,则可以利用C ++库。

如果程序本质上是相同的,但是具有附加功能,则说它是同一程序并不是完全错误的。它相同,但也不同。

大多数C程序员至少可以做一点C ++,反之亦然

将这样的人称为C / C ++程序员并不是没有道理的。是的,他们可能专门研究一种语言,但是有谁是称职的C或C ++程序员,却实际上不能使用任何其他语言?从某种意义上说,不是他们都是 C / C ++程序员吗?

说“ C / C ++”没有错。重要的是被理解

英语不是表达三段论的工具。您可以将英语用于逻辑,但仅此而已,并且会付出很大的努力。

这是因为单词并不自然具有确切的含义,而是含糊不清的含义和内涵云。重要的是人们是否理解您在说什么。


5
@BЈовић他们对于一小部分术语的可接受性不同意您的意见,因此您得出的结论是,他们不了解其中的区别并且不称职。这是很不合理的事情。
2015年

4
@ el.pescado是的。您会发现人们实际上是在指PHP / JavaScript。为什么不?重点是要理解,而不是玩文字游戏。

10
@BЈовић你没有道理。它们不是“完全不同的”。C ++是比C 大得多的语言,但它几乎包含所有C语言。有一些不兼容性会阻止C ++成为适当的超集,但它们很小,就像其他保留字一样,还需要进行一些强制类型转换,但这仅是其中的一部分。它几乎是一个适当的超集,只是不完全是。
2015年

7
@BЈовић也许您不明白我写的是什么。您为什么不看这里,看看如何在每种情况下都可以改编C程序,使其也可以编译为C ++。david.tribble.com/text/cdiffs.htm#C99-vs-CPP9

7
@BЈовић如果您是个术语专家,您应该意识到C不是“ 功能性 ”的,而是“ 过程性的 ”-在您对他人的无能指控之前,您可能希望了解这种区别。
RM

15
  1. 我应该停止使用术语C / C ++吗?

绝对。除了可能混淆使用C和C ++代表使用该术语的人之外,尚不清楚该构造体打算表达什么。

由于这种困惑是造成挫折感的普遍原因,因此许多人对此感到非常激动,仅凭这个词的出现就足以使他们对您的贡献变得消极。这看似愚蠢,但这似乎是我们所拥有的。

我建议您不要谈论“ C / C ++”,而是使用一个实际上可以清楚说明您的意思的术语。

  • 如果您谈论的是C语言中可能对C ++也可能不正确的事情,只需说C即可

    示例: 应如何main在C中声明该函数?

    乍一看,C ++的答案似乎是相同的:int main()int main(int, char**)。但是随着讨论的进行,可能需要指出的是,在C ++中,必须在全局范围内声明函数,这在C语言中没有意义,因为它没有namespaces。另一方面,C允许main递归调用,而C ++不允许。在C ++中,return 0;如果您“失败” ,则存在一个隐式,main但在C中return,任何路径上都需要该语句。清单继续进行,如果您事先弄清楚要讨论的语言是什么,它将使讨论变得更加简单。

  • 如果您谈论的是C ++中可能不适合C的事情,只需说C ++即可

    例如: 将一malloc()的ED阵列int小号最初是全零在C ++?

    C的简短答案恰好是相同的:不。但是随着答案的继续,可能值得指出的是,在C语言中,calloc这将是一个很好的选择,而在C ++语言中,使用a std::vector<int>可能是一个更好的选择。

  • 如果要指出C和C ++之间的相似之处,请说C和C ++

    示例: 在C和C ++中,sizeofan int是定义的实现,在编译器和体系结构之间可能有所不同。

    在这里,我们要指出C和C ++的行为方式相同。我们正在明确地谈论这两种语言。

实际上,我建议您更加具体,不仅要谈论“ C”或“ C ++”,还要谈论确切的版本。两种语言都在发展,诸如

C ++支持/* … */// …注释,而C仅支持/* … */样式。

既不对也不对。

  1. 如果对#1的回答是肯定的,那么我将如何调用混合使用C和C ++的程序?

由于语言重叠,因此每个C程序都将包含看起来像C ++的部分,反之亦然。但是,作者可能会选择使用C或C ++编译器。所以说,“该计划是写在ç ”如果它是一个C编译器和“程序是写在编译C ++ ”,如果他们使用C ++编译器,即使他们可能会拒绝使用任何现代C ++的功能。有些人将此类C ++代码称为C样式C ++。缺少重载,异常,多态性,模板和I / O流是此类代码的共同特征。

相反,如果有些文件是用C语言编写,并编译了一个C编译器和一些其他文件都用C ++编写,并用C ++编译器,然后编译链接在一起的目标文件,我会说,“该方案是写在一个实际上,您已经做到了C和C ++的混合 ”。

但是,如果相反,如果作者非常小心地编写每个文件,使得可以使用C C ++编译器对其进行编译,而生成的程序将执行相同的操作,则可以说“用C和C ++的通用子集编写。”

对于在C和C ++代码之间共享的头文件,通常是后者。顺便说一句,编写这样的代码并不容易。如果您想进一步强调的是,只有这样的结构中使用的是C和C ++有效,并通过不同的编译器厂商广泛支持,术语一个便携式 C和C ++的公共子集可以用来强调这一点。

  1. 假设这两种语言都是“不同的”语言,那么C ++编译器是否有可能在某些时候停止支持用C语言编写的代码(因为现代C ++在指针,动态内存处理等基本内容上与C语言有所不同)?

我不确定我是否理解这个问题。由于C和C ++ 不同的语言,因此您不能期望其中的一个编译器接受为另一个编写的程序。但是,编译器通常以模块化的方式进行设计,如果编译器具有C ++ 前端,则很有可能也会具有C前端。(然后,您可以通过命令行开关或类似的方法选择要使用的语言。)只要两种语言都将被广泛使用,这似乎不太可能改变。我认为关于“现代C ++”的观点基本上是关于好的编码标准和标准库的问题。从编译器的角度来看,两种语言的发展都趋于融合而不是发散。

  1. 现在,为保持兼容性而制定C / C ++标准的人们之间是否存在任何协作?

是。C ++ 11和C11中引入的内存模型和原子操作库就是一个很好的例子。似乎两种语言的设计者都意识到兼容性很重要,并且正在努力改进它。就个人而言,我希望合作更加紧密,两个ISO工作组甚至可以参加,但是我的愿望并不重要。

Bjarne Stroustrup在《 C ++编程语言》第四版的第44.3节中谈论了C和C ++的各种版本之间的区别和共性,具有讽刺意味的是,该标题为“ C / C ++兼容性”。在这种情况下,使用该术语实际上可能是适当的,因为很清楚是什么意思。

  1. 如果#4是肯定的,那么这种合作可能会在不久的将来随着现代C ++的出现而结束(11/14/17)

如上所述,它发生在C ++ 11中,并且有望/希望/需要再次发生。


怎么可能不是对与错?
JDługosz

4
它没有如“绿色的东西很昂贵”这样的陈述所定义的真实值。对于C和C ++版本的特定组合,它是正确的,而对于其他版本,它是错误的。
5gon12eder 2015年

5

C / C ++是C和C ++的交集。

int new;不是C / C ++,也不是vector<int> foo;

同样,C89 / C99是这两种语言的交集,不允许enum bool { false, true };for(int i = 0;;)不允许。

还有C ++ 11 / C ++ 14等

可以编写在C ++ 11和C ++ 14下编译(并正确运行)的代码,即使在一个编译下并不意味着它在另一个编译下。实际上,很多人都这样做。

许多人编写的代码可以在C和C ++中使用。

显然,重叠越大,其意义就越大;我不希望看到有关C / C ++ / Java代码的任何问题。


尽管谈论这些语言的公共子集确实是“有道理的”,但许多问题在该子集中将没有答案,例如main()在C和C ++中应该返回什么?

但是您可以谈论适用于多种语言规范的代码,无论这些规范是通过“版本”还是“语言名称”或其他方式区分的。


3

这是对以下一些回答的一种回应:“这是一个适合紧紧工作的程序员的代码,并且在管理环境中还可以”,在其他一些答案和评论中也可以看到。


我认为即使是那种解释也应谨慎对待。

至少从90年代中期开始,如果您需要C ++程序员,而自称是C程序员的人,则必须询问他们对面向对象设计的了解程度,以及对对象进行调试的经验。面向上下文,以及它们使用模板库的能力。您想在面试和录用过程中准确地探究那些问题。

另一方面,自从C ++专家开始推动“现代C ++”以来,已经有十多年的历史了,这意味着强调从裸露的指针转向更安全的指针对象和基于迭代器的习惯用法。随着C ++ 11的出现,现在已经对多范式编程提供了明确的支持,并且大力推动不显示任何裸指针的代码。这就是说,如果我今天采访了一位C ++程序员以担任C职位,那么我将非常担心检查此人对启用脚踩射击的实际指针的熟悉程度。

这些天我不从事业务(甚至达到了Stack Overflow处于起步阶段的程度),所以我不敢猜测任何一位假想的受访者都不会具备交叉技能,但是我认为,现在最常用的语言确实已经大不相同了。

简而言之,不仅在技术环境中,而且在大多数业务环境中,都应删除“ C / C ++”。


指出其含义是“ C或C ++,谁知道”,“ C和C ++,链接在一起”,“ C和C ++,交点”还是“ C或C ++,谁在乎”的好方法即使人们可以以某种方式摆脱困境,它也越来越缺乏正当性。
Deduplicator 2015年

2

最简单的回答这个问题,你应该永远使用该词。这是一个不应该存在的术语。没有任何意义 每个程序都是C或C ++。

直到出现C ++ x0,C ++ 11(或一般来说是现代的C ++ 11/14/17)之前,这都是安静的事实。

C ++ 98和03甚至都不是带有类的远程C语言。谁教过你这个都不知道,你可以忘记他们。这永远是不正确的。


这并非完全正确。曾经有一页描述了一种名为“ C / C ++”的语言的拟议语言规范,该规范除其他外规定了(几乎)不存在类型系统。遗憾的是,此页面已被删除,托管该页面的网站此后放置了robots.txt文件,该文件删除了archive.org中的存档副本。
greyfade 2015年

1
啊哈,我在archive.is上找到了一个副本:基本 原理语法和语义
greyfade 2015年

5
“每个程序都是C或C ++。” 我不同意。采取C程序,然后一次将其移植到C ++ 一个文件中(通过更改一个文件的编译器选项)是很常见的。某些文件可能永远不会移植,并永远保持为C。这样的程序是用C和C ++编写的
nikie

并不是的。该程序由子程序组成,每个子程序都是C或C ++。就编译器而言,每个TU(即整个程序)都被编译为C或C ++。
DeadMG

3
不是“每个程序都是C或C ++”。Bjarne Stroustrup教授说:“写得很好的C往往也是合法的C ++。例如,Kernighan&Ritchie中的每个示例:“ The C Programming Language(第二版)”也是C ++程序。stroustrup.com/bs_faq.html#C-is-subset

1

从概念上讲,设计C源文件没有特别困难,因此它们也可以使用C ++进行原样编译。这样做确实可以带来一些明显的好处。例如,在为嵌入式系统编写代码时,有时能够在托管PC环境中测试代码会有所帮助。如果代码可以像C ++一样干净地编译,则可能会有类似“ MOTOR_ENABLE = 1;”的语句。写入嵌入式系统上的易失性I / O位(编译为C),但在PC上触发仿真逻辑(编译为C ++)。也有可能在PC上设计一种C ++类型,其行为方式类似于uint16_t在较小的嵌入式系统上的行为(因此,例如,给定u16 x=65533;,编译器将不得不考虑的值)。x*x作为九个,而不是自由支配地做任何想要的事情),尽管到目前为止我的仿真器都没有包含(部分原因是我使用的C ++编译器在这种情况下没有做任何古怪的事情)。

不幸的是,C程序员和C ++程序员彼此之间有足够的反感,使得这些语言多年来以兼容的方式发展。当C89尝试改编C ++的一些更有用的功能(例如函数原型)时,似乎已经出现了一种态度,即希望C ++的任何功能的程序员都应使用C ++,而忽略了在许多情况下会使用C ++的事实。能够使用C ++的某些功能(例如,使用静态或静态内联链接重载函数的能力,而不必接受与不需要的其他功能相关的成本(例如,与导出相关的名称处理)的功能,会有所帮助重载的功能)。

尽管C89和C ++ 98的交集是一种可行的语言,但是C的较新版本与C ++的较新版本的可用超集可能会缩小而不是增加(由于严格的别名规则),并且趋势倾向于裂缝不断增加。


1
什么是“ C ++ 95”?技术报告?
Ben Voigt,2015年

1
如果要为内部函数重载,但不希望对外部函数进行名称修饰,则可以将前者置于匿名状态,然后namespace将后者声明为extern "C",然后使用C ++编译器。
5gon12eder

@ BenVoigt:Mea culpa。我应该查一下。C99之前的C ++版本。当C89出现时,它试图使C更像C ++,但是C99添加了许多C ++绝对不感兴趣的功能(例如,可变长度数组)。我用C ++编程的次数不多,但我认为比起各种不同的功能,更多的C ++功能对C的帮助更大。
2015年

@ 5gon12eder:我从未尝试将C ++代码链接到C项目。是否真的像使所有内容都是静态/内联一样简单,还是具有extern "C"其他复杂性(例如,静态对象初始化等)?C ++中有什么方法可以使它foo(1234)调用foo_const(1234)宏,而foo(x)[哪里x不是常量]会调用foo_var(x)函数?嵌入式代码中有很多情况,对于“函数”来说可能有意义,例如SET_PORT(port, state)根据端口和状态是否都为三种形式...
supercat

...编译时常量,端口是常量,但状态不是,或者端口和状态都不是常量。有什么方法可以使用模板或其他标准C ++机制来完全完成此操作,还是只能在具有gcc扩展名的编译器上实现?
2015年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.