Create extern char array in C - c

How to create an external character array in C?
I have tried various ways to define char cmdval[128] but it always says undefined reference to 'cmdval'
I want to put a string in cmdval in first.c file and use it in other second.c file. I tried adding a global.h file with extern char cmdval[128] but no luck.
UPDATE:
global.h
extern char cmdval[128];
first.c
#include "global.h"
char cmdval[128];
function(){
strcpy(cmdval, "a string");
}
second.c
#include "global.h"
function(){
printf("%s \n",cmdval); //error
}
FAIL :( "undefined reference to `cmdval'"
EDIT:
I am working in linux (editing a mini OS xv6 then compiling and running it in qemu), I don't know if it is a barrier

You need to declare it in the .h file
extern char cmdval[128];
And then define the value in first.c;
char cmdval[128];
Then anything that includes your .h file, provided it is linked with first.o will have access to it.
To elaborate, "extern" is saying, there is an external variable that this will reference... if you dont then declare cmdval somewhere, cmdval will never exist, and the extern reference will never reference anything.
Example:
global.h:
extern char cmdval[128];
first.c:
#include "global.h"
char cmdval[128];
int main() {
strcpy(cmdval, "testing");
test();
}
second.c:
#include "global.h"
void test() {
printf("%s\n", cmdval);
}
You can compile this using:
gcc first.c second.c -o main
Or make the .o files first and link them
gcc -c first.c -o first.o
gcc -c second.c -o second.o
gcc first.o second.o -o main

Extern doesn't mean find it somewhere, it changes the variable linkage to external, which means no matter how many time you declare a variable, it references to the same thing.
e.g. These references the same thing in c(not c++), a global variable's linkage by default is external.
external char cmdval[128];
char cmdval[];
char cmdval[128];
The problem is that you shoud first compile them into .o, then link those .o together.
gcc -c first.c second.c
gcc -o first.o second.o
or
gcc first.c second.c

You should have a compilation unit in which you define the cmdval variable. The extern keyword only declares that the variable exists, it does not define it.
Put the following line in first.c, second.c or in an other C file of your choice:
char cmdval[128];

In second.c
#include "global.h"
define extern char cmdval[128] in global.h as well.

Related

C compiler can't find function definition

I'm new to C programming and encounter this question:
Three files: main.c, foo.h, foo.c are in the same directory.
main.c:
#include <stdio.h>
#include "foo.h"
int main(){
printf("%d",func(1));
}
foo.h declares function func:
int func(int);
foo.c defines function func:
#include "foo.h"
int func(int a){
return a+1;
}
This code works as expected, but when I rename the definition file foo.c into something else, say bar.c, then main.c throw an error during compilation saying:
LLVM ERROR: Program used external function _func which could not be resolved!
I know that the definition file doesn't need to have the same name as the header file. Why the linker can't find the appropriate definition after I renamed foo.c into bar.c?
More generally, how does the linker search for function definition? Search every .c files in the same directory, one by one? Only search for definition in the .c file, which has the same file name as header file?
EDIT:
I was using code-runner IDE on MacBook, don't know how the IDE actually compiles the source files.
Add the file name in the compilation command:
$ gcc -o main main.c foo.c && ./main
^^^^^

C - Makefile compiles after header file changes, but changes dont take effect

I have 3 files in this program, lab4.c, functions.h, functions.c
The lab4.c calls a function multiply(), whose prototype is in functions.h and is defined in functions.c. Multiply then used multiple other functions from functions.c. The only includes I have for this is in lab4.c including functions.h, do I need more? The problem I am having is described below
lab4:
#include <stdio.h>
#include <stdlib.h>
#include "functions.h"
int main(void) {
...
}
functions.h:
#ifndef FUNCTIONS
#define FUNCTIONS
void divideByPowerOf2(unsigned int* a, int power);
void multiplyByPowerOf2(unsigned int* a, int power);
...
#endif /* FUNCTIONS */
functions.c:
void divideByPowerOf2(unsigned int* a, int power){
*a >>= power;
}
void multiplyByPowerOf2(unsigned int* a, int power){
*a <<= power;
}
...
Currently, my makefile looks like this:
Makefile:
#Makefile
all: lab4
lab4: lab4.o functions.o functions.h
gcc -Wall -o lab4 lab4.o functions.o
lab4.0: lab4.c
gcc -c lab4.c
functions.o: functions.c
gcc -c functions.c
now this will recompile when I change the header file, but the changes dont actually take effect. For example, if I change the header file to
#ifndef FUNCTIONS
#define FUNCTIONS
void divideByPowerOf2(unsigned int* a, int power);
//void multiplyByPowerOf2(unsigned int* a, int power);
...
#endif /* FUNCTIONS */
the program still works just fine. Im assuming I may have messed up linking the files with includes and everything, as that usually confuses me. For example, does functions.c need to refer to anything? and does functions.h need any kind of reference to the .c files? How do I get this to work properly so that if I change the header file, it recompiles and actually uses the new header
Thanks for any help!
First, there's a typo here:
lab4.0: lab4.c
should be
lab4.o: lab4.c
then, your function.h should be on the source => object dependency lines, not on the object => executable line, else, if you change the .h file, it just re-links without rebuilding the .o files: it changes nothing.
Moreover, it's good to use -Wall, but you have to use it when you compile your files, not when you link the executable, or you'll miss the actual compilation warnings (-Wall during the link phase only is pretty useless).
For instance, the -Wall flag would show you that commenting a prototype generates an "implicit declaration" warning (which can lead to an improper call/return values of a function). It's even more effective with -Werror, which turns warnings into errors, so you cannot ignore warnings.
Here's how your makefile should look like:
all: lab4
CFLAGS = -Wall
lab4: lab4.o functions.o
gcc -o lab4 lab4.o functions.o
lab4.o: lab4.c functions.h
gcc $(CFLAGS) -c lab4.c
functions.o: functions.c functions.h
gcc $(CFLAGS) -c functions.c
note that if you only have 2 source files and they're small enough, you could even not use the make file by just running:
gcc -Wall -o lab4 lab4.c functions.c
in a script. That's not adapted if you have too many / big source files, because it rebuilds everything everytime.

Make .c file as a library error

I have a test.c file which contains main() function and some test cases and it cannot be modified it(such as adding "include *.h"). Then I have a foo.c file which contains some functions(no main() function). These functions will be tested through test cases in test.c file. What I'm going to do is use foo.c as a library and link it to test.c file. And here is the simple code.
test.c
//cannot modify
int main(){
...
bar();
...
}
foo.c
#include "foo.h" //I will explain this below.
int bar(){
...
}
I'm trying to implement an interface using .h file, such as
foo.h
#ifndef _FOO_H_
#define _FOO_H_
extern int bar();
#endif
Then using cmd line
gcc -c foo.c
gcc -o output test.c foo.o
./output
You may guess the result. There is a warning that "implicit declaration of function 'bar' is invalid in C99 [-Wimplicit-function-declaration]". And the test.c file cannot run correctly.
Could someone help me about this? Thank you so much!
Your problem is:
test.c has a call to bar() in it.
test.c doesn't have any declaration for bar, nor does it have an #include for a .h file that declares bar.
You are not allowed to change test.c in any way to add either a declaration or an #include.
This is a hard problem. The C language requires there be a prototype/declaration for bar in test.c! It can be written directly in the test.c file (write extern int bar(); before you call it), or the declaration can come in from another file with an #include statement, but you must have it.
Luckily, GCC has a way to force an #include statement into a file while it's compiling the file. You don't have to change test.c in order to make it start with #include "foo.h". This will solve your problem:
gcc -c -include foo.h test.c
You need to include the declaration of bar in the test.c file:
#include "foo.h"
So that the compiler have the prototype in the translation unit, of test.c.

Using my own library : implicit declaration of function

Firstly, I'd like to thanks you in advance for the time you'll take to help me out. If I may suggest you, you can try reproduce my problem. Don't try to read the makefiles if you don't feel it'll help you to understand my problem.
Also, I'd like to point out the fact I did a lot of researches and I don't have find any solution.
My Environment
Eclipse (with CDT)
Windows (cygwin) (but I also tried on Ubuntu)
I want to use my own (shared) library in a project.
My Setup
My Shared Library
mylib.h
#ifndef MYLIB_H_
#define MYLIB_H_
extern int foo();
#endif /* MYLIB_H_ */
mylib.c
#include "mylib.h"
extern int foo() {
return 1;
}
My Project
I added my library as a reference :
Project Properties - C/C Generals - Paths and Symbols - References (tab) - Check off mylib (Active)
foo.c
#include <stdlib.h>
int main(int argc, char **argv) {
return foo();
}
Problem
I'm getting implicit declaration of function 'foo' [-Wimplicit-function-declaration] warning when I build my project. This warning only occurs when I build my project while my library project has nothing to build (because it hasn't been modified since the last build).
Console output
Info: Internal Builder is used for build
gcc -std=c99 "-ID:\\Users\\cmourgeo\\maximo workspace\\mylib" -O0 -g3 -Wall -c -fmessage-length=0 -o "src\\uselib.o" "..\\src\\uselib.c"
..\src\uselib.c: In function 'main':
..\src\uselib.c:12:2: warning: implicit declaration of function 'foo' [-Wimplicit-function-declaration]
return foo();
^
gcc "-LD:\\Users\\cmourgeo\\maximo workspace\\mylib\\Debug" -o uselib.exe "src\\uselib.o" -lmylib
Should I provide eclipse my own makefiles ? (under C/C++ / Builder Settings)
Solution
I had to include my header in foo.c
#include "../src/mylib.h"
The path is kind of weird because of my projects structures :
myproject
src
foo.c
mylib
src
mylib.c
mylib.h
Thanks to user590028 for helping me getting through that !
In foo.c you forgot to include the mylib.h header
/* foo.c */
#include <stdlib.h>
#include "mylib.h" /* <-- include this line */
int main(int argc, char **argv) {
return foo();
}
You should include
extern int foo();
in foo.c
then you can compile:
gcc -c mylib.c
gcc mylib.o foo.c -o foo
and execute:
./foo
As you are using eclipse, maybe it compiles corret after including the extern line and it's not needed to compile manually.

Can't figure out error with shared variables

source.c ::
int source=0;
int desti=0;
char str[50]="";
source.h::
extern int source;
extern int desti;
extern char str[50];
station1.c
#include"source.h"
#include<stdio.h>
main()
{
printf("%d %d",source,desti);
}
When I compile station1.c I get the following error:
undefined reference to 'desti'
undefined reference to 'source'
Could anyone please tell me where I have gone wrong?
What did your compile command line look like?
Try:
cc -c station1.c -o station1.o
cc -c source.c -o source.o
cc -o a.out station1.o source.o
The first two compile the files by themselves and puts the result in a .o file.
The last line combines the .o files into an executable named 'a.out'.
When we use extern modifier with any variables it is only declaration i.e. memory is not allocated for these variable. Hence in your casecompiler is showing error unknown symbol source & desti. To define a variable i.e. allocate the memory for extern variables it is necessary to initialize the variables.
initialize the variables in source.c
or another way is to compile with combining the object file
gcc -c source.c station1.c -Isource.h

Resources