Skip to main content
Stack Overflow
  1. About
  2. For Teams

Return to Answer

added 35 characters in body
Source Link
Eric Postpischil
  • 233.8k
  • 15
  • 199
  • 383

You appear to be working with old code. In GCC version 10, the default behavior changed.

tag_parameters g_tagParams[TAG_POSITIONS_MAX]; is not a definition but is a tentative definition. (In spite of its name, a tentative definition is not a definition, the same way a prospective employee on a job interview is not an employee.) However, when a translation unit (a source file being compiled, including the headers it includes) contains a tentative definition for an identifier but no definition for it, the compiler creates a definition.

When you compile multiple such translation units and linked them together, there are multiple definitions. This is not actually an error according to the C standard. The standard left this undefined so that different C implementations could treat it differently, as such practices already existed. In GCC prior to version 10, definitions induced by tentative definitions were classified as "common" definitions and were coalesced during linking, meaning that the multiple common definitions were reduced to a single definition. This was traditional Unix behavior.

ThereHere are two ways you can get the code working indeal with this respectissue:

  • You can add the switch -fcommon to your GCC compilation commands. This requests the old behavior, that GCC mark the definitions resulting from tentative definitions as common.
  • You can change every tentative definition to a declaration that is not a tentative definition by prefixing it with extern, as in extern tag_parameters g_tagParams[TAG_POSITIONS_MAX];. Then, in one source file, not a header, provide a tentative definition, tag_parameters g_tagParams[TAG_POSITIONS_MAX];. (You can also make this a proper definition by adding an initializer, tag_parameters g_tagParams[TAG_POSITIONS_MAX] = { 0 };.)

Some further explanation is here .

You appear to be working with old code. In GCC version 10, the default behavior changed.

tag_parameters g_tagParams[TAG_POSITIONS_MAX]; is not a definition but is a tentative definition. (In spite of its name, a tentative definition is not a definition, the same way a prospective employee on a job interview is not an employee.) However, when a translation unit (a source file being compiled, including the headers it includes) contains a tentative definition for an identifier but no definition for it, the compiler creates a definition.

When you compile multiple such translation units and linked them together, there are multiple definitions. This is not actually an error according to the C standard. The standard left this undefined so that different C implementations could treat it differently. In GCC prior to version 10, definitions induced by tentative definitions were classified as "common" definitions and were coalesced during linking, meaning that the multiple common definitions were reduced to a single definition. This was traditional Unix behavior.

There are two ways you can get the code working in this respect:

  • You can add the switch -fcommon to your GCC compilation commands. This requests the old behavior, that GCC mark the definitions resulting from tentative definitions as common.
  • You can change every tentative definition to a declaration that is not a tentative definition by prefixing it with extern, as in extern tag_parameters g_tagParams[TAG_POSITIONS_MAX];. Then, in one source file, provide a tentative definition, tag_parameters g_tagParams[TAG_POSITIONS_MAX];. (You can also make this a proper definition by adding an initializer, tag_parameters g_tagParams[TAG_POSITIONS_MAX] = { 0 };.)

You appear to be working with old code. In GCC version 10, the default behavior changed.

tag_parameters g_tagParams[TAG_POSITIONS_MAX]; is not a definition but is a tentative definition. (In spite of its name, a tentative definition is not a definition, the same way a prospective employee on a job interview is not an employee.) However, when a translation unit (a source file being compiled, including the headers it includes) contains a tentative definition for an identifier but no definition for it, the compiler creates a definition.

When you compile multiple such translation units and linked them together, there are multiple definitions. This is not actually an error according to the C standard. The standard left this undefined so that different C implementations could treat it differently, as such practices already existed. In GCC prior to version 10, definitions induced by tentative definitions were classified as "common" definitions and were coalesced during linking, meaning that the multiple common definitions were reduced to a single definition. This was traditional Unix behavior.

Here are two ways you can deal with this issue:

  • You can add the switch -fcommon to your GCC compilation commands. This requests the old behavior, that GCC mark the definitions resulting from tentative definitions as common.
  • You can change every tentative definition to a declaration that is not a tentative definition by prefixing it with extern, as in extern tag_parameters g_tagParams[TAG_POSITIONS_MAX];. Then, in one source file, not a header, provide a tentative definition, tag_parameters g_tagParams[TAG_POSITIONS_MAX];. (You can also make this a proper definition by adding an initializer, tag_parameters g_tagParams[TAG_POSITIONS_MAX] = { 0 };.)

Some further explanation is here .

Source Link
Eric Postpischil
  • 233.8k
  • 15
  • 199
  • 383

You appear to be working with old code. In GCC version 10, the default behavior changed.

tag_parameters g_tagParams[TAG_POSITIONS_MAX]; is not a definition but is a tentative definition. (In spite of its name, a tentative definition is not a definition, the same way a prospective employee on a job interview is not an employee.) However, when a translation unit (a source file being compiled, including the headers it includes) contains a tentative definition for an identifier but no definition for it, the compiler creates a definition.

When you compile multiple such translation units and linked them together, there are multiple definitions. This is not actually an error according to the C standard. The standard left this undefined so that different C implementations could treat it differently. In GCC prior to version 10, definitions induced by tentative definitions were classified as "common" definitions and were coalesced during linking, meaning that the multiple common definitions were reduced to a single definition. This was traditional Unix behavior.

There are two ways you can get the code working in this respect:

  • You can add the switch -fcommon to your GCC compilation commands. This requests the old behavior, that GCC mark the definitions resulting from tentative definitions as common.
  • You can change every tentative definition to a declaration that is not a tentative definition by prefixing it with extern, as in extern tag_parameters g_tagParams[TAG_POSITIONS_MAX];. Then, in one source file, provide a tentative definition, tag_parameters g_tagParams[TAG_POSITIONS_MAX];. (You can also make this a proper definition by adding an initializer, tag_parameters g_tagParams[TAG_POSITIONS_MAX] = { 0 };.)
lang-c

AltStyle によって変換されたページ (->オリジナル) /