Rule 8.4 - How are tentative definitions handled

Moderators: misra-c, david ward

Post Reply
misra-c
Posts: 571
Joined: Thu Jan 05, 2006 1:11 pm

Rule 8.4 - How are tentative definitions handled

Post by misra-c » Thu Dec 19, 2013 8:25 am

Which of the following are compliant with rule 8.4?

Code: Select all

extern int32_t  ext_val0 = 3;

       int32_t  ext_val1 = 3

extern int32_t  extval2;              
       int32_t  extval2 = 3;

       int32_t  ext_val3;                 
       int32_t  ext_val3 = 3;

       int32_t  ext_val4; 
---
Posted by and on behalf of
the MISRA C Working Group

misra-c
Posts: 571
Joined: Thu Jan 05, 2006 1:11 pm

Re: Rule 8.4 - How are tentative deinfitions handled

Post by misra-c » Thu Dec 19, 2013 8:31 am

This will depend on the presence of other definitions as to whether the Tentative definition is treated as a declaration or a definition.

Code: Select all

extern int32_t  ext_val0 = 3;   // Non-compliant - definition and no declaration

       int32_t  ext_val1 = 3;   // Non-compliant - definition and no declaration

extern int32_t  extval2;        // Compliant - declaration
       int32_t  extval2 = 3;    // followed by compatible definition

       int32_t  ext_val3;       //  Compliant - Tentative definition, but treated as declaration
       int32_t  ext_val3 = 3;   //  because followed by compatible definition

       int32_t  ext_val4;       // Non-compliant -   Tentative definition, 
                                // which becomes a definition, initialising ext_val4 to 0.
---
Posted by and on behalf of
the MISRA C Working Group

gdavis
Posts: 3
Joined: Tue Oct 05, 2010 11:48 pm
Company: Green Hills Software

Re: Rule 8.4 - How are tentative definitions handled

Post by gdavis » Mon Apr 09, 2018 4:18 pm

The answer is clear, but I don't understand the reasoning. It would seem better to me if a tentative definition were to be treated as a definition for the sake of this rule. Otherwise, this rule permits something like the following:

Code: Select all

/* header.h */
uint16_t var;           /* tentative definition */
uint16_t get_value(void);

Code: Select all

/* file1.c */
#include  "header.h"
uint16_t var = 3;     /* true definition */

Code: Select all

/* file2.c */
#include  "header.h"
uint16_t get_value(void) { return var; }
Many of the popular compilers come from a UNIX background where such tentative definitions are emitted as a "common" in the object file, a technique borrowed from Fortran. This extension is typically on by default even in strict language modes. When this happens, the multiple definitions of var that occur in both file1.c and file2.c won't be diagnosed by the user's linker.

While this sort of code violates other MISRA rules like 8.5 and 8.6, I don't see anything to be gained by relying on a system rule to catch something that should be caught within a single translation unit.

It is true that these popular compilers have a switch to turn off common variables (for example, GCC has -fno-common).
But, there's no loss of expressiveness by requiring a declaration that is not a tentative definition. In anything, it also helps to avoid mistakes of the sort:

Code: Select all

const uint8_t foo;
uint8_t func() {
    /* It would appear that this function just returns 0, but it actually returns 1.  */
     return foo;
}
... // many lines of code
const uint8_t foo = 1;
My suggestion would be to add a sentence to the end of the amplification to the effect of:

For the purposes of this rule, a tentative definition is considered a definition.

This might go well with a rule to prohibit tentative definitions for external symbols. (There is a slight use-case for tentative definitions of static symbols, though).

Thanks for your time, and keep up the good work.

Best Regards,

-Greg

misra-c
Posts: 571
Joined: Thu Jan 05, 2006 1:11 pm

Re: Rule 8.4 - How are tentative definitions handled

Post by misra-c » Tue Apr 24, 2018 10:31 am

Thank you for your comments. We will consider it when we next review this rule.
---
Posted by and on behalf of
the MISRA C Working Group

Post Reply

Return to “8.8 Declarations and defnitions”