1

Problem: A variable 'VarOriginal' is defined in source C file under pragma say 'parameterX' and declared as an extern variable in a header file under the same pragma 'parameterX'. There is a process using it in which it is known that the variable is shown declared in some other header file where this variable is not present at all.

As a Workaround:I declared one more different variable 'VarNew' before the pragma 'parameterX' in the header file and similarly defined the variable 'VarNew' before the line where 'VarOriginal' was defined. And it all worked.

Header file: header_file_with_problem.h

#ifndef HEADER_FILE_WITH_PROBLEM_H

#define HEADER_FILE_WITH_PROBLEM_H

#include "ABC.h"

declare variable 'VarNew' here <------

#pragma BSS(".parameterX")

extern int VarOriginal;

#pragma BSS(DEFAULT_SECTION_BSS)

Source C File:

#define  HEADER_FILE_WITH_PROBLEM_C

#include "XYZ.h"

#include "header_file_with_problem.h"

declare variable 'VarNew' here <------

#pragma BSS(".parameterX")

int VarOriginal;

#pragma BSS(DEFAULT_SECTION_BSS)

But I am not able to understand why the problem was coming earlier. Why was the linker not able to find the definition of 'VarOriginal' in the source file and now it is able to do so, after declaring another variable before 'VarOriginal' itself?

Also, this problem is not with all source and header files present in the folder, but only a few of them.

8
  • You should show a minimal example. You don't even mention what pragma. That is relevant info. We are not psychic, we're just humans Commented Sep 29, 2011 at 22:14
  • 1
    Also, please edit your post to use meaningful variable names. A variable "A"... and pragma say "X" and a "B" before "A" and "J" and say "C" and maybe "Y" or "Z" reads like nonsense and makes it very hard to understand your actual problem. Also remember that we can't see your monitor from here; the only information we have is what you provide us. The more clearly and concisely you can state your question, the more likely you'll get help quickly. Commented Sep 29, 2011 at 22:17
  • How did pragma even creep in here at all? The question was about some variable that was extern. Commented Sep 29, 2011 at 22:26
  • @PeteWilson Probably because the OP is using #pragma once instead of regular multiple inclusion guards Commented Sep 29, 2011 at 22:27
  • Oh, yes. That must be it. But that would cause the problem he's seeing, right? Commented Sep 29, 2011 at 22:29

1 Answer 1

3

I don't see anything defined in your source file. The

extern int VarOriginal;

is still a non-defining declaration, regardless of where you put it (source file or header file). There's not a single variable definition in your code sample, so no wonder the linker is complaining about missing definitions.

In order to define a variable in your C file you need to do either

int VarOriginal; /* no `extern` !!! */

or add an explicit initializer

extern int VarOriginal = 0; /* definition */

A mere

extern int VarOriginal; /* not a definition!!! */

that you seem to have there now (according to what you posted) is not a definition.

Sign up to request clarification or add additional context in comments.

9 Comments

Thank you.. this was useful to me. But I have already used int VarOriginal; in the source file. I have corrected that in my question above.
Hmmm...which compiler(s) accept extern int VarOriginal = 0; /* definition */? You can't mix an initializer with extern.
@Jonathan Leffler: Why not? Since the beginning of time it was perfectly legal to mix an initializer with extern. extern can be used with both declarations and definitions. Speaking informally, when used with declarations (non-defining ones) it has "import" semantics. When used with definitions it has "export" semantics. In this case extern int VarOriginal = 0; is a definition (because of the initializer) and extern explicitly gives it external linkage ("exports" it).
This extern is, of course, redundant, since the object would have external linkage by default. But it is not illegal. Some compilers believe that extern should be (or "usually is") reserved for variable declarations only. They assume that user made a mistake by adding extern to a variable definition and issue a warning for that (GCC does, for one example). But nevertheless formally it is not an error.
Which beginning of time? FWIW, clang (Apple LLVM version 6.1.0 (clang-602.0.53) (based on LLVM 3.6.0svn)) on Mac OS X objects with: xx.c:1:12: warning: 'extern' variable has an initializer [-Wextern-initializer] extern int VarOriginal = 0; /* definition */. That was a plain clang -c xx.c. I'm surprised that's only a warning — it was always a violation of the standard.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.