为什么下面的代码中没有编译或运行时错误?

时间:2016-09-03 17:51:59

标签: c++ c compilation

我偶然发现了以下。编译器编译以下代码时没有任何错误或警告。请帮我理解为什么编译器没有抛出任何错误?该程序只包含双引号中的字符串。

我没有声明任何char数组也没有将以下字符串分配给任何变量。

> head(t16.df$text)
[1] "It's hard, but here's how to support innovation via @HarvardBiz  #innovation #startup #create "      
[2] "Do you want to work for someone else your entire life ? #startup #success #entrepreneur #business #inspiration"            
[3] "RT @StartGrowthHack: How to start a #startup? What is the process to make it a #success. #Entrepreneur "                    
[4] "RT @ipfconline1: #Startup: Outbound #Marketing vs #InboundMarketing >> The Best Is to Use a Mix of Both #GrowthHack…"
[5] "Understanding and using marke #FolaDanielSpeaks Call +2348034163006 to Book Fola Daniel to speak, train or compere"        
[6] "RT GrowthHackers: The Process of Creating Trello #startup  -via biconnections"  

4 个答案:

答案 0 :(得分:10)

因为任何表达式都是有效的陈述。

"Why is there no error in compilation?";

是一个语句,由一个表达式组成,该表达式的计算结果为给定的文字字符串。这是一个完全有效的陈述,恰好没有任何效果。

答案 1 :(得分:1)

当然,“有用的”陈述更像是

a = b;

但是很好;

b;

也是有效语句。在你的情况下,b只是字符串文字;你可以自由地将它放在一个方法体内。显然这个声明没有任何副作用;但如果声明类似

,该怎么办?
"some string " + someFunctionReturningString();

您可能希望执行该表达式;作为副作用,那个被调用的方法,不是吗?

答案 2 :(得分:1)

使用-Wunused-value标志编译程序。它只是提出

warning: statement with no effect "Why there is no error in compilation?"; ^

就是这样。

如果您使用-Wall标志编译上述代码,它也会说

warning: return type of ‘main’ is not ‘int’ [-Wmain] void main() {

答案 3 :(得分:1)

void main()
{
    "Why there is no error in compilation?";
}

首先,让我们解决字符串文字。 表达式语句在任何语句有效的任何上下文中都有效,它由(可选)表达式后跟分号组成。评估表达式并丢弃任何结果。 (空语句,仅由分号组成,被归类为表达式语句;我不确定原因。)

表达式语句非常常见,但通常在表达式具有副作用时使用。例如,赋值(x = 42;)和函数调用(printf("Hello, world\n"))都是表达式,两者都是屈服值。如果您不关心结果,只需添加分号即可获得有效的声明。

并非所有表情都有副作用。在没有任何副作用的表达式中添加分号(正如您在此处所做的那样)(字符串文字是表达式)通常不常用,但语言并不禁止它。一般来说,C可以让你做你想做的事情,让你担心它是否有意义,而不是强加一些可以防止错误的特殊情况规则,但也可能阻止你做一些有用的事情。

现在让我们封面void main()。很多人会告诉你,有些理由认为这是错误的,正确的定义是int main(void)。这几乎是正确的,这是一个很好的建议,但细节要复杂得多。

对于托管实现(基本上是提供标准库的实现),main可以用以下三种方式之一定义:

int main(void) { /* ... */ }

int main(int argc, char *argv[]) { /* ... */ }

或等效的," 或其他一些实现定义的方式。" (有关详细信息,请参阅N1570第5.1.2.2.2节。)这意味着允许特定实现记录和实施除{2}之外的main形式。特别是,编译器可以(并且有些人)在其文档中声明

void main() { /* ... */ }

和/或

void main(void) { /* ... */ }

对于该编译器是有效的。如果您无论如何写void main(),并且不需要明确支持void main()的编译器。它不是语法错误或约束违规;它只是有不明确的行为。

对于独立实现(基本上是针对没有操作系统的嵌入式系统,并且不需要支持大多数标准库),入口点完全是实现定义的;它甚至不需要被称为main。要求void main()对于此类实现并不罕见。 (您可能正在使用托管实施。)

说了这么多,如果你正在使用托管实现,你应该总是定义main一个int返回类型(在C中你应该int main(void)而不是int main())。没有充分的理由使用void main()。它使你的程序不可移植,并且让像我这样讨厌的学生厌烦地讨论如何定义main

许多C书建议您使用void main()。如果你看到这个,记住谁写了这本书,并避免该作者写的任何东西;他或她不太了解C,很可能会犯其他错误。 (我特别想到Herbert Schildt。)这里有一个很大的讽刺是void关键字是由1989 ANSI C标准引入的 - 引入main要求的标准相同返回int(除非实现明确允许其他内容)。

到目前为止,我已经讨论了C规则。您的问题被标记为C和C ++,并且C ++中的规则略有不同。在C ++中,函数声明或定义上的空括号具有不同的含义,您应该编写int main()而不是int main(void)(后者在C ++中受支持,但仅用于与C兼容)。 C ++要求main为托管实施返回int,并且没有权限允许实现支持void main()