Avoid redefinition of alias variable for weak reference in header-file - c

I have a variable in an header file:
myHeader.h
uint16 dummyVar = 0;
extern const uint16 myVar __attribute__((weak,alias("dummyVar")));
So when I don't link the parts where myVar gets defined, the linker will just give it the value of the symbol dummyVar.
My problem is, that I am working on a Project with a given architecture, where my Header-File myHeader.h is included by several C-Files. Because of that I get multiple definitions of dummyVar . But when I define dummyVar outside of my header it doesnt work anymore for my __attribute__ since dummyVar needs to be defined when it is assigned as an alias.
Is there any way I can work around this without changing the basic architecture of this?

A simple solution would be to to just declare it as follows:
static uint16 dummyVar = 0;

Related

How to define a const struct to make a consant

I'm trying to make a const struct so I can use is values as constant
For this purpose I have write this code:
typedef struct __PIN{
GPIO_TypeDef GPIO;
uint16_t pin;
}__PIN;
const struct __PIN PA1 = {.GPIO=GPIOA,.pin=GPIO_PIN_5};
But When I compile it prompt me whit the following error:
"multiple definition of 'PA1' "
but it's only defined in this file!
in fact the its said that is defined first in the same file and line that prompt the error:
.../CUSTOM/GPIO_custom/GPIO_lite_s.h:27: multiple definition of `PA1'; .../CUSTOM/GPIO_custom/GPIO_lite_s.h:27: first defined here
what is going on?
should I do this on a different way?
additional info:
-this is the header of a library that Im making, I want this constant value to be accesible to all files that include this header.
-Im programming on a STM32 board (STM32F411CEU6) using STM32CubeIDE 1.10.1
-I included the main.h so I can use the uint8_t like variables
-this files is currently being included in 2 files, main.c and another .c file, deleting its include in either of those files seems to fix the problem, but I don't know why.
any help would be very much appreciated!

how to solve this c linker error?

uint8 *measurements[30] = {(uint8*)0x0041c620};
I have declared a global variable in my program like above but I am getting a linker error as
LNK2005: _measurements already defined in MAIN.obj
I am modifying the code as
typedef unsigned char uint8;
uint8 *measurements[30];
measurements[30]= {(uint8*)0x0041c620}
;
then also I am getting the error
The error tells you that you have defined this global variable in more than one translation unit - in MAIN.obj as well as in some other. Which one I cannot tell, because you didn't post the whole error message, only one line of it.
Your question does not contain enough information to reproduce the problem, or tell where exactly you made the error. Perhaps you defined the variable in a header file?
Is the definition in a header file? If so, you'll get one definition of the variable for each source file that includes the header. Try marking changing the header to only declare the variable, not define it, like so:
extern uint8_t *measurements[30];
and then define it in one of the files, e.g. main.c like so:
uint8 *measurements[30] = {(uint8*)0x0041c620};
It seems you want array of 30 8-bit values, and that array is already existing at some specific address.
In one source file (measurements.c):
uint8 * const measurements = (uint8*)0x0041c620;
In header file (measurements.h):
uint8 * const measurements;
Usage:
#include "measurements.h"
// In some function
measurements[29] = ... // Set last element to something
Note that I added the const because I think you do not want to change array address (0x0041c620).

Two static variables in same name(two different file) and extern one of them in any other file

Declaring a variable as static in one file and do a extern declaration in another file - i thought this will give an error while linking as the extern variable will not be seen in any object, as the one which declared in other file was with qualifier static. But somehow the linker(renesas) didn't show any error and created executable.
If the above usecase was correct, what will happen if 2 variables be declared as static in 2 different files and another in another file with extern declaration? In this case 2 different memories will be created in 2 different objects, but which one of the variable will be linked for other variable was declared as extern in another file(as both the variable name are same)??
file1.c
static int test_var;
fn1()
{
test_var = 1;
}
file2.c
static int test_var;
fn2()
{
test_var = 2;
}
file3.c
extern int test_var;
fn3()
{
int x;
x = test_var;
}
In your example, file3.c has absolutely no access to variable test_var in either file1.c or file2.c. You should get a linking error if test_var is not declared within the scope of file3.c.
In file1.c and file2.c, the keyword static means the variable test_var is file scope. That means this variable only accessible in the the file where it's declared.
In the file3.c, the keyword extern means the variable is declared in other file.
When the compiler compile the file3.c, it will mark the variable test_var is in other object file, and doesn't care where is it. So this file can be compiled, and no errors occurred.
But when the linker process this object files, it will found that no variable named as test_var can be link to file3, an error will be shown.
The answer is probably in a way you have configured linker. If you are linking library everything will be OK here and file3.o module will have test_var reference as UNDEFINED.
If you're linking application from this 3 modules you will fail just because absence of main() routine definition and unresolved external will be considered even less evil. :-)
Just to check it please examine appropriate *.o modules symbol tables in your build process and then final result. Having such approach you will find the reason of your strange build behavior.

Header File being included twice

I am relatively new to C (as I don't want to use C++, or at least just yet) and I'm not sure how to fix my include error I am having.
I have a header file containing the constant value of 1000 and is called Test.
const int Test = 1000;
I have this file included in 2 files - Myfile.c and Myfile2.c each including the file as such:
#include "MyHeader.h"
My project will not build/compile and as I have found out it is including the header twice which is not allowed as I am declaring my variable "Test" twice. Upon research I found this on Wikipedia: http://bit.ly/10wPraP
I used this "Include Guard"
Example:
#ifndef MY_HEADER
#define MY_HEADER
const int Test = 1000;
#endif
and I have also tried the pre-processor(?) command pragma once.
#pragma once
However, my program still will not build. I now get error saying that the varibale "Test" is already defined in MyFile.obj.
I thought this might be a Visual Studio-ism as I am using that but both my 2010 Express C++ and VS2003 Professional wont build this. I have tried cleaning the project within Visual Studio and I am not sure what else to do.
Am I being very silly and missing something obvious here and that is why it isn't work?
I am used to C# and "using" with namespaces rather than includes. May my setting on VS to only compile C code be effecting this?
Include guards have nothing to do with it. You need to separate the declaration from the definition and have only one definition (this is called the "one definition rule", ODR):
header.h:
extern const int n;
one source file:
#include "header.h"
const int n = 1000;
all other source files:
#include "header.h"
Useful Reference:
Wikipedia on the extern keyword: https://en.wikipedia.org/wiki/External_variable
Wikipedia on the One Definition Rule: https://en.wikipedia.org/wiki/One_Definition_Rule
The problem is with the way that header files are processed when you #include them: Header files are literally copied and pasted into the body of your C files. This means that Myfile.c and Myfile2.c both have their own declarations of an int named Test - essentially creating two different versions of the one variable. The linker then complains about having two different variables with the same name.
The solution is to put the const int Test = 1000; in one of your C files, and to add extern const int Test; to MyHeader.h. This way, the variable is declared only once, and all files are aware of the one variable because the extern directive tells them that another file has the variable Test they are looking for.
MyHeader.h
extern const int Test;
Myfile.c (for instance)
#include "MyHeader.h"
...
const int Test = 1000;
Myfile2.c
#include "MyHeader.h"
...
<use Test>
This is correct. You have two source files that are defining Test. You should only define this once. Since header files get included all over the place, they should generally only declare variables, not define them. e.g.
header:
const int Test;
Exactly one c file:
const int Test = 1000;
Define that variable in any one of the .c file and declare that as extern in the header files.
#ifndef MY_HEADER
#define MY_HEADER
extern const int Test;
#endif
In Myfile.c define the variable
const int Test = 1000;

What is wrong with using extern in C like that?

I've already searched something abou this but I've still don't understand it..
file1.h
extern int *game_array[5];
Player.c
#include "file1.h"
void *delete_player(player_struct *player)
{
... //some code
game_array[5] = 5; //undefined reference to `game_array`
... //some code
}
When I don't use extern it "work's fine" = I can build it withou errors, but the program's not finished ..
I suppose the using extern is fine but something is wrong ..
I want to use this game_array ... array of games on server from all my .c source files, there's only one instance of this array in my aplication.
You need to define game_array in one of your .c files, and compile/link that file into your executable.
The definition will look like this:
int *game_array[5];
What your file1.h is saying is basically "There exists a variable called game_array somewhere in my project, and it has such-and-such type". However, the variable doesn't actually exist until you've defined it somewhere (typically, in a .c file).
The extern keyword basically means that the compiler should not complain about the symbol, even if it's not defined, because it will be available at link-time.
So if it's not defined at link-time, you'll obviously have errors.
You need to provide an implementation in one of your C file:
Something like:
#include "file1.h"
int * game_array[ 5 ];
void * delete_player( player_struct * player)
{
...
Writing extern int *game_array[5]; means that somewhere, in some file, there's an actual definition for game-array -- i.e., a declaration without the extern. You're failing to provide that, so the linker complains that the actual variable doesn't exist anywhere.

Resources