Recently I had an issue where a function was apparently linking to a constant, causing an abort when executed. The problem was introduced because of bad code, but it brought up questions about the linker.
There was a macro with the same name as a constant structure; The file that was trying to use the macro didn't include the header where it was defined. This implicitly defined the function, which is to be expected. What was unexpected was that it linked to a constant, which was not a function or pointer-to a function. I am using version 4.6 of the TMS470 compiler. Here's a summary of the offending code:
Structure defined elsewhere:
typedef struct {
uint8_t *addr;
uint8_t first_bit;
uint8_t last_bit;
}Byte_Bit_Fld_T;
Header A:
extern const Byte_Bit_Fld_T Not_A_Function;
C File A:
const Byte_Bit_Fld_T Not_A_Function =
{(uint8_t *) &var[6] /*uint8_t array*/, 1, 1 };
Header B (no longer included):
extern some_structure
#define Not_A_Function() \
( some_structure.some_member )
C File B:
//#include "header_B" header with macro is no longer included
if ( ( 0 != SOME_OTHER_MACRO() ) && ( !some_bool || !Not_A_Function() )
// Not_A_Function is implicitly declared and gets linked to the constant from header A
I would expect this code to cause a type error, since Not_A_Function is not a function or pointer-to a function, and there's no cast. Otherwise I would expect there to be undefined symbols and a link error. Is there any chance this could be compiler error, or are my assumptions about the linker wrong? Normally, a compiler error is one of the last things I look for, but they do happen. I'd really like to know what's going on here, even though this can be prevented by writing better code.