C11标准要求声明标识符的类型,禁止隐式函数声明,C90标准允许隐式的确定变量
和函数的类型。因此,一些现有的遗留代码使用隐式类型,一些C编译器为了支持遗留
代码仍然允许隐式类型,但是新的代码不应该再使用。这样的实现可以选择使用隐式
声明,并继续翻译,以支持使用这个特性的现有程序。
1、隐式int
C不再允许不指定类型的声明,C11标准6.7.2节表示:
每个声明的声明指示符中至少应该有一个类型指示符。
异常代码例子:extern foo;
这个异常的例子省略了类型指示符,一些C翻译器并不会在遇到违反这个约束
情况时产生诊断信息,这些不合格的C翻译器会继续处理这类声明,把类型
隐式的当做int。
修改后的例子:extern int foo;
2、隐式函数声明
不允许隐式函数声明,每个函数必须在调用前被显式声明。在C99标准中,
如果一个被调用的函数没有显示声明原型,编译器会为它提供一个隐式声明。
C90标准包含了下面的需求:
如果在一个函数调用中,带括号的实参列表前面的表达式只由一个标识符
组成,并且看不到这个标识符的声明,这个标识符将被隐式的声明,就像在
最内层的代码块中包含了这个函数调用时出现了extern int identifier()这个声明。
如果一个函数的声明在被调用的地方不可见,C90兼容平台会为其假定一个隐式
声明 extern int indentifier();
这个声明暗示这个函数可以取任何数量和类型的参数并返回一个int型数据。而如果
遵守当前C标准,程序员必须在每个函数调用前显式的声明函数原型。符合C标准的
应用可以遵守也可以不遵守隐式函数声明,但是如果遇到使用未声明的函数时,C需要
产生诊断信息。
在下面这个异常示例中,如果malloc()函数没有被显式声明或被包含在stdlib.h中,只遵守
C90标准的编译器会隐式声明malloc()函数为int malloc()。如果系统平台的int长度是32位,但是
指针长度是64位,那么本例中的结果就会导致返回的指针被截断,返回一个32位的整型。
如果使用微软Visual Studio 2013 64位编译平台,这个异常代码例子最终会导致一个非法
访问错误。
修改后的代码为:
3、隐式返回类型
不要声明具有隐式返回类型的函数,如果一个函数返回一个有意义的整型值,就把它的
返回类型声明为int,如果返回无意义的值,就声明为void。
异常代码示例:
因为编译器假设foo()返回一个int 类型的值,因此UINT_MAX被不正确的转换为-1.
修改后的代码为:
修改后的例子中,foo()返回类型被定义为unsigned int,因此函数正确返回了UINT_MAX.