Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Comment: Changed C24 -> C23

The C Standard does not allow for implicit typing of variables and functionsC23 Standard requires type specifiers and forbids implicit function declarations. The C90 Standard did allow such allows implicit typing of variables and functions.   Consequently, there exists some existing legacy code that uses implicit typing.   Some C compilers still support legacy code by allowing implicit typing, but it should not be used for new code.   Because implicit declarations lead to less stringent type checking, they can introduce unexpected and erroneous behavior or even security vulnerabilities.The C Standard requires type identifiers and forbids implicit function declarations. After issuing the diagnostic, Such an implementation may choose to assume an implicit declaration and continue translation to support existing programs that used this feature.

Noncompliant Code Example (Implicit int)

C no longer allows for the absence of type specifiers in a declaration. In these cases, the type is defined to be that of a signed int.Do not rely on implicit int typing. Section The C Standard, 6.7.3 paragraph 2 of the C Standard  [ ISO/IEC 9899:20112024 ], states:

Except where the type is inferred (6.7.10), at At least one type specifier shall be given in the declaration specifiers in each declaration, and in the specifier-qualifier list in each struct member declaration and type name.

This noncompliant code example omits the type specifier:

Code Block
bgColor#FFCCCC
langc
extern foo;

Most Some C implementations do not issue a diagnostic for the violation of this constraint. Many These nonconforming C translators will continue to treat such declarations as implying the type int.

Compliant

...

Solution (Implicit int)

This compliant solution explicitly includes a type specifier:

...

Implicit declaration of functions is not allowed: ; every function should must be explicitly declared before it can be called. In C89C90, if a function is called without an explicit prototype, the compiler provides an implicit declaration.

The C90 Standard Standard [ISO/IEC 9899:1990] includes this requirement:

If the expression that precedes the parenthesized argument list in a function call consists solely of an identifier, and if no declaration is visible for this identifier, the identifier is implicitly declared exactly as if, in the innermost block containing the function call, the declaration extern int identifier(); appeared.

If a function declaration is not visible at the point at which a call to the function is made, C90-compliant platforms assume an implicit declaration of extern int funcidentifier();.

This declaration implies that the function may take any number and type of arguments , and returns a single return an int. However, to conform with C99, you to the current C Standard, programmers must explicitly prototype every function before invoking it. An  An implementation that conforms to C99 or later the C Standard may or may not perform implicit function declarations. However, C99 does require the but C does require a conforming implementation to issue a diagnostic if it encounters an undeclared function being used.

In the following this noncompliant code example, if malloc() is not declared, either explicitly , or by including stdlib.h, a compiler that conforms only to C90 may implicitly declare malloc() as int malloc(). (Compilers that only comply with C90 are required to provide an implicit declaration of malloc().)  If If the platform's size of int is 32 bits, but the size of pointers is 64 bits, the resulting pointer could would likely be truncated as a result of the implicit declaration of malloc(), returning a 32-bit integer.

 

Code Block
bgColor

...

#FFCCCC
langc
#include <stddef.h>
/* #include <stdlib.h> is missing */
 
int main(void) {
  for (size_t i

...

 

...

= 0; i < 100; ++i) {
    /* int malloc() assumed */
    char *ptr = (char *)malloc(0x10000000);

...


    *ptr = 'a';
  }
  return 0;
}

Implementation Details

When compiled with Microsoft Visual Studio (2013 for a C9064-only bit platform), the above this noncompliant code example will eventually cause an access violation when dereferencing ptr in the loop.

Compliant Solution (Implicit Function Declaration)

In this This compliant solution , declares malloc() is explicitly declared before it is used. by including the appropriate header file:

Code Block
bgColor#ccccff
langc
void *malloc(size_t size);#include <stdlib.h>
 
int main(void) {
  for (size_t i;
  for (i = 0; i < 100; ++i) {
    char *ptr = (char *)malloc(0x10000000); /* int malloc() assumed */
    *ptr = 'a';
  }
  return 0;
}

For more information on function declarations, see see DCL07-C. Include the appropriate type information in function declarators.

Compliant Solution (Implicit Function Declaration)

This compliant solution declares malloc() by including the appropriate header file.

Code Block
bgColor#ccccff
langc
#include <stdlib.h>
 
int main(void) {
  size_t i;
  for (i = 0; i < 100; ++i) {
    char *ptr = (char*)malloc(0x10000000); /* int malloc() assumed */
    *ptr = 'a';
  }
  return 0;
}

Noncompliant Code Example (Implicit Return Type)

Similarly, do Do not declare a function with implicit an implicit return type. If it returns For example, if a function returns a meaningful integer value, declare it it as returning int. If it returns no meaningful value, declare it it as returning void.

Code Block
bgColor#ffcccc
langc
#include <limits.h>
#include <stdio.h>
 
foo(void) {
  return UINT_MAX;
}

int main(void) {
  long long int c = foo();
  printf("%lld\n", c);
  return 0;
}

Because the compiler assumes that foo() returns a value of type int for this noncompliant code example, UINT_MAX is incorrectly converted to −1.

Compliant Solution (Implicit Return Type)

This compliant solution explicitly defines the return type of foo() as unsigned int:. As a result, the function correctly returns UINT_MAX .

Code Block
bgColor#ccccff
langc
#include <limits.h>
#include <stdio.h>

unsigned int foo(void) {
  return UINT_MAX;
}

int main(void) {
  long long int c = foo();
  printf("%lld\n", c);
  return 0;
}

Risk Assessment

Because implicit declarations lead to less stringent type checking, they can introduce unexpected and erroneous behavior. Occurrences of an omitted type specifier in existing code are rare, and the consequences are generally minor, perhaps resulting in abnormal program termination.

Rule

Severity

Likelihood

Remediation Cost

Priority

Level

DCL31-C

low

Low

unlikely

Unlikely

low

Low

P3

L3

Automated Detection

Tool

Version

Checker

Description

Astrée
Include Page
Astrée_V
Astrée_V

type-specifier

function-return-type

implicit-function-declaration

undeclared-parameter

Fully checked
Axivion Bauhaus Suite

Include Page
Axivion Bauhaus Suite_V
Axivion Bauhaus Suite_V

CertC-DCL31Fully implemented
Clang
Include Page
Clang_V
Clang_V
-Wimplicit-int
Compass/ROSE

 

 




Coverity
Include Page
Coverity_V
Coverity_V
MISRA C 2012 Rule 8.1Implemented
Cppcheck Premium

Include Page
Cppcheck Premium_V
Cppcheck Premium_V

premium-cert-dcl31-cPartially Implemented
Can detect implicit int
 

ECLAIR

Include Page
ECLAIR_V
ECLAIR_V
decltype

CC2.DCL31

Fully implemented

GCC
Include Page
GCC_V
GCC_V

 


Can detect violations of this rule when the -Wimplicit and -Wreturn-type flags are used

Helix QAC

Include Page
Helix QAC_V
Helix QAC_V

C0434, C2050, C2051, C3335Fully implemented
Klocwork
Include Page
Klocwork_V
Klocwork_V
IF_MISS_DECL

CWARN.IMPLICITINT
MISRA.DECL.NO_TYPE
MISRA.FUNC.NOPROT.CALL
RETVOID.IMPLICIT

 

Fully implemented

LDRA tool suite
Include Page
LDRA_V
LDRA_V

24 D


, 41 D, 20 S


, 326 S, 496 S

Fully implemented

PRQA QA-C Include PagePRQA_VPRQA_V

0434 (C)
1302
2050
2051
3335

Parasoft C/C++test
Include Page
Parasoft_V
Parasoft_V
CERT_C-DCL31-a
All functions shall be declared before use
PC-lint Plus

Include Page
PC-lint Plus_V
PC-lint Plus_V

601, 718, 746, 808

Fully supported

Polyspace Bug Finder

Include Page
Polyspace Bug Finder_V
Polyspace Bug Finder_V

CERT C: Rule DCL31-C


Checks for:

  • Types not explicitly specified
  • Implicit function declaration

Rule fully covered.

PVS-Studio

Include Page
PVS-Studio_V
PVS-Studio_V

V1031
SonarQube C/C++ Plugin
Include Page
SonarQube C/C++ Plugin_V
SonarQube C/C++ Plugin_V
S819, S820  Partially implemented; implicit return type not covered.
RuleChecker
Include Page
RuleChecker_V
RuleChecker_V

type-specifier

function-return-type

implicit-function-declaration

undeclared-parameter

Fully checked
TrustInSoft Analyzer

Include Page
TrustInSoft Analyzer_V
TrustInSoft Analyzer_V

type specifier missing

Partially verified (exhaustively detects undefined behavior).

Fully implemented

Related Vulnerabilities

Search for vulnerabilities resulting from the violation of this rule on the CERT website.

Related Guidelines

Key here (explains table format and definitions)

Taxonomy

Taxonomy item

Relationship

CERT C Secure Coding StandardDCL07-C. Include the appropriate type information in function declaratorsPrior to 2018-01-12: CERT: Unspecified Relationship
ISO/IEC TR 24772:2013Subprogram Signature Mismatch [OTR]Prior to 2018-01-12: CERT: Unspecified Relationship
MISRA C:2012
 
Rule 8.1 (required)Prior to 2018-01-12: CERT: Unspecified Relationship

Bibliography

[ISO/IEC 9899:
2011
1990]
[ISO/IEC 9899:2024]
Section
Subclause 6.7.
2
3, "Type Specifiers"
[Jones 2008]
 

...



...

Image Modified Image Modified Image Modified