是否有不需要标准库的C / C ++编译器?

时间:2009-11-16 15:50:53

标签: c++ c compiler-construction

我们公司的所有申请人必须通过一个简单的测验,使用C作为早期筛选过程的一部分。

它由C源文件组成,必须对其进行修改才能提供所需的功能。我们明确指出,我们将尝试按原样编译文件,不做任何更改。

几乎所有申请人都使用“strlen”,但其中一半不包含“string.h”,因此在我加入之前它不会编译。

他们只是懒惰还是那些不需要你包含标准库文件的编译器,比如“string.h”?

10 个答案:

答案 0 :(得分:13)

GCC将很乐意按原样编译以下代码:

main()
{
   printf("%u\n",strlen("Hello world"));
}

它会抱怨incompatible implicit declaration of built-in function ‘printf’strlen(),但它仍会产生可执行文件。

如果使用-Werror进行编译,则无法编译。

答案 1 :(得分:3)

我很确定编译器包含不需要的标头是不符合的。这样做的原因是C标准表示如果包含相关标题,则保留各种名称。我认为这意味着如果它们不包括在内,它们就不会被保留,因为编译器不允许保留标准未说保留的名称(除非它们包含一个非标准的标题,恰好由编译器,并在其他地方记录以保留额外的名称。使用POSIX时会发生什么。

这并没有完全回答你的问题 - 确实存在不符合规范的编译器。至于你的申请人,也许他们只是习惯于包含“windows.h”,所以以前从未想过C标准可能定义了什么标题strlen。我假设没有测试,MSVC原则上要求你包含“string.h”。但是因为“windows.h”为你做了这些,对于绝大多数实用的Windows程序,你不需要知道你必须包含“string.h”。

答案 2 :(得分:3)

他们可能很懒,但你不能说。标准库实现(与编译器相反,当然每个编译器通常都有“自己的”stdlib impl。)允许包含其他头文件。例如,#include <stdlib.h>可以包括标准中描述的每个其他库。 (我在“C / C ++”的背景下谈论,而不是严格来说C。)

因此,程序员习惯于这样的事情,即使没有严格的保证,也很容易忘记某些函数是否来自像stdlib.h这样的普遍捕获 - 很多人忘记了{{1也来自string.h。

如果他们不包含任何标头,我会认为它们是错误的。但是,如果你不允许他们用特定的实现来测试它,那么很难说它们是错的。如果你没有为他们提供手册页(代表他们需要知道如何在工作中使用的资源),那么错误。

那时,你当然可以说不遵循标准的确切字母;但是你是否希望编程人员完成任务并知道如何在他们看到问题时解决问题,或者是那些担心无关紧要的编程人员?

答案 3 :(得分:2)

如果您提供一个C文件开始使用,请使其具有从头开始可能需要的所有标题,并要求申请人删除未使用的标题。

答案 4 :(得分:2)

最常见的工程经验是向应用程序添加(或删除)几行代码,数千行已经正常工作。在这种情况下,在添加对printf()或strlen()的调用时需要另一个头文件是极其罕见的。

看看经验丰富的工程师的肩膀会很有意思 - 不仅仅是从学校毕业,而是在战壕中有丰富的经验 - 看看他们是否只是添加了strlen()和尝试编译,或者如果他们在编译之前检查是否已经包含stdlib.h或string.h。我敢打赌,绝大多数做前者。

答案 5 :(得分:1)

C实现通常仍然允许隐式函数声明。

无论如何,我不会认为所有样板都是面试的必要部分,除非你特别要求(例如“请不要忽略你在源头通常拥有的任何东西)文件“)。

(使用Visual Assist的“添加...包含”我知道他们来自哪里;)

答案 6 :(得分:0)

大多数编译器都提供某种强制标头包含的选项。

EG。 GCC编译器有-include选项,它等同于#include预处理程序指令。

答案 7 :(得分:0)

TCC也会愉快地编译一个文件,例如接受的答案的例子:

int main()
{
        printf("%u\n", strlen("hello world"));
}

没有任何警告(除非你通过-Wall);作为额外的奖励,你可以调用tcc -run file.c来执行file.c而无需先编译输出文件。

答案 8 :(得分:0)

在C89(最常用的标准)中,未声明的函数将被假定为返回int并具有未知参数,并将进行编译(可能带有警告)。如果没有,那么编译器就不合规了。另一方面,如果您将代码编译为C ++则会失败,如果C ++编译器符合要求,则必须这样做。

为什么不简单地在问题中指明必须包含所有必需的标题(可能省略不相关的标题)。

或者,将候选人放在带有编译器的计算机上,让他们检查自己的代码,并声明代码必须在最大警告级别编译,而不发出警告。

答案 9 :(得分:0)

我正在做C / C ++ 20年(甚至是教授课程),我想有50%的可能性我忘记了包含(99%的时候我编码,包含已经在那里了)。我知道这并不能完全回答你的问题,但如果有人知道strlen(),他们会在几秒钟内知道如何处理特定的编译器错误,所以从工作资格的角度来看,这个漏洞实际上是无关紧要的。

而不是强调这样的东西,检查需要真正理解语言的微妙之处应该更加相关,即缓冲区溢出,strncpy不会在达到极限时附加最终\ 0,要求某人制作一个安全(截断)复制到有限长度的缓冲区等。特别是在C / C ++编程中,生成编译器错误的错误会导致您/您公司真正的麻烦。