Per the C standard section 7.1.3 Reserved identifiers
All identifiers that begin with an underscore are always reserved for use as identifiers with file scope in both the ordinary and tag name spaces.
and
If the program declares or defines an identifier in a context in which it is reserved (other than as allowed by 7.1.4), or defines a reserved identifier as a macro name, the behavior is undefined.
I understand that the referenced 7.1.4 is for the note 187 stating:
Because external identifiers and some macro names beginning with an underscore are reserved, implementations may provide special semantics for such names. For example, the identifier _BUILTIN_abs could be used to indicate generation of in-line code for the abs function. Thus, the appropriate header could specify
#define abs(x) _BUILTIN_abs(x)
Now, the common pattern (as shown in many reputable online resources, including numerous SO questions/answers) to define linker script symbols with leading underscores such as
.bss :
{
. = ALIGN(4);
_bss_start = .;
*(.bss)
*(.bss*)
. = ALIGN(4);
_bss_end = .;
} >RAM
and then refer to these symbols in the C code by declaring like
extern char _bss_start[];
extern char _bss_end[];
or similar. From the cited standard excerpts I gather that these declarations are undefined behavior. Is that correct or I am misreading something? Is there any proper naming convention for linker exported symbols that do not violate the C standard (I understand that we can simply use the proper C naming, but apparently there is some reason people insist on the special naming)?