I have written a simple code like this
#include <stdlib.h>
#include <stdio.h>
//#define CONFIG_TARGET_X86_64
#ifdef CONFIG_TARGET_X86_64
static void A( )
{
printf("A\n");
}
#else
void A( );
#endif
static void B( )
{
printf("B\n");
}
static int xx( )
{
#ifdef CONFIG_TARGET_X86_64
return 1;
#else
return 0;
#endif
}
int main(void)
{
if (xx( )) /* define CONFIG_TARGET_X86_64 */
A( );
else
B( );
}
If we don't define the CONFIG_TARGET_X86_64, xx( ) will always return FALSE, so functiopn A which is only declared, but not implemented will never be called(dead code).
compile it with gcc -O0
/tmp/cctSpgGk.o: In function `main':
1.c:(.text+0x34): undefined reference to `A'
collect2: error: ld returned 1 exit status
But it can be compiled by -O1 or higher.
use GCC V6.1.0
It seems that one of the optimization options in the -O1 option eliminates the dead code, I have seen the optimize doccument about GCC
https://gcc.gnu.org/onlinedocs/gcc-6.4.0/gcc/Optimize-Options.html
but I can't find it.
So I just want to compile this code under the -O0 option, Is it possible ? Are there some optimization flags help me to do this?
Thanks
What's worth noting here is this declares a method signature:
void A( );
Where this declares a method implementation:
void A( ) { };
There is a huge difference between these two.
If you're referencing a function with a call you need to implement it. The compiler will decide if it'll optimize that function call away or not depending on other factors, but it'll need to know what that function does, not just how it's called.
You can declare A as weak:
void A (void) __attribute__ ((weak));
Then the linker will ignore the undefined symbol reference, but a call to this function will lead to a crash.
Related
I'm working on a simple class List, but when compiling the header and cpp file, I get the error: undefined reference to `main'
What am I doing wrong, and how could I fix this?
Here is the list.h file that has simple headers:
list.h
#ifndef LIST_H
#define LIST_H
#include <string>
const int DEFAULT_CAPACITY = 100;
class List
{
public:
List();
List(int capacity);
~List();
void push_back(std::string s);
int size() const;
std::string at(int index) const;
private:
std::string* mData;
int mSize;
int mCapacity;
};
#endif
And here is the list.cpp file:
list.cpp
#include "list.h"
#include <string>
List::List(){
mData = new std::string[DEFAULT_CAPACITY];
mSize = 0;
mCapacity = 100;
};
List::List(int capacity){
mData = new std::string[capacity];
mSize = 0;
mCapacity = capacity;
};
List::~List(){
delete[] mData;
};
void List::push_back(std::string s){
if (mSize<mCapacity){
mData[mSize] = s;
mSize++;
}
};
int List::size() const{
return mSize;
};
std::string List::at(int index) const{
return mData[index];
};
I tried experimenting around with "using namespace std" and how to include , but I can't figure out how to get these errors to go away. What is causing them?
You should be able to compile list.cpp, you can't link it unless you have a main program. (That might be a slight oversimplification.)
The way to compile a source file without linking it depends on what compiler you're using. If you're using g++, the command would be:
g++ -c list.cpp
That will generate an object file containing the machine code for your class. Depending on your compiler and OS, it might be called list.o or list.obj.
If you instead try:
g++ list.cpp
it will assume that you've defined a main function and try to generate an executable, resulting in the error you've seen (because you haven't defined a main function).
At some point, of course, you'll need a program that uses your class. To do that, you'll need another .cpp source file that has a #include "list.h" and a main() function. You can compile that source file and link the resulting object together with the object generated from list.cpp to generate a working executable. With g++, you can do that in one step, for example:
g++ list.cpp main.cpp -o main
You have to have a main function somewhere. It doesn't necessarily have to be in list.cpp. And as a matter of style and code organization, it probably shouldn't be in list.cpp; you might want to be able to use that class from more than one main program.
Undefined reference to main() means that your program lacks a main() function, which is mandatory for all C++ programs. Add this somewhere:
int main()
{
return 0;
}
My project has the following 4 files: main.c, rcm.h, rcm.c and queue.c.
In rcm.h I'm declaring all functions implemented in rcm.c and queue.c.
rcm.c looks like:
#include "rcm.h"
void rcm (void) {
Queue *Q = init(10);
/* Some other stuff */
}
queue.c` looks like:
#include "rcm.h"
extern inline Queue* init(int n) {
return malloc(sizeof(Queue*);
}
and rcm.h:
#ifndef __RCM__
#define __RCM__
typedef struct queue { /*...*/ } Queue;
void rcm( void );
inline Queue* init( int n );
#endif
When compiling I get the the warnings
gcc-7 -O0 -c rcm.c -o rcm.o
In file included from rcm.c:15:0:
rcm.h:58:15: warning: inline function 'init' declared but never defined
inline Queue* init(int size);
^~~~
gcc-7 -c queue.c -o queue.o
gcc-7 main.c lib/rcm.o queue.o -o main
In file included from main.c:4:0:
inc/rcm.h:58:15: warning: inline function 'init' declared but never defined
inline Queue* init(int size);
^~~~
But, when I am not declaring init() as inline compiles normally.
inline Queue* init( int n );
In order for a compiler to be able to inline a function, it must know he code of a function. Without that knowledge, the compiler must emit a call to that function1. Hence the warning. In order to use an inline function in several modules, you can define it in the header as:
static inline Queue* init (int n)
{
/* code here */
}
Cf. for example the GCC documentation for inline.
The reason for the warning is that you want the function to be inline, but you are hiding the code from the compiler: main.c includes the header that declares an inline function but in that compilation unit, init is defined (implemented) nowhere.
1 Except for functions built-in the compiler. In that case, you don't have to provide the code yourself, it compiler has build-in knowledge about it.
I am using GCC version 8.2
On several pieces of code, I use small functions. On each one of the functions, I have tests (i.e. Unity framework tests). The tests are defined as #define macros, testing very specific things. For instance, if a number if positive.
Now, when compiling the code using -Wextra flag, I am getting warning about unused variables, although I am using them on the defined macros.
The question is, GCC does not recognize a macro as using a variable, or am I missing something?
Example:
#define compare(a,b) ( ((a) == (b)) ? 1 : 0 )
...
void f() {
int a;
a = f1();
if(compare(a,123))
printf("It works");
}
In this case, GCC would warning about unused variable a, although it is being used by the macro (besides being attributed a value by function f1()).
This is not the case, at least with the example you supplied. Here is a Minimal, Complete, and Verifiable demonstration:
#include <stdio.h>
#define compare(a,b) ( ((a) == (b)) ? 1 : 0 )
int f1() {
return 42;
}
void f() { // your code
int a;
a = f1();
if (compare(a, 123))
printf("It works");
}
int main(int argc, char *argv[]) {
f();
return 0;
}
When compiled with gcc -Wall -Wunused (yes, this is redundant) using gcc 8.2 or 7.3 there are no warnings or errors.
I am just a beginner in C++. I am trying to construct some header file header.h, but the output is always like the following:
/tmp/ccTmZKXX.o: In function `main':
main.c:(.text+0x13): undefined reference to `func'
collect2: ld returned 1 exit status
Could you please help me to see whether my way of using header file is correct or not? Thanks a lot!
Main code (main.c):
#include "stdio.h"
#include "func.h"
main() {
double a = f(2.3);
printf("a=%f\n", a);
}
where func.c contains:
double func (double x) { return x ;}
where func.h contains:
double func (double);
And I compile with:
gcc -o main main.c
There are multiple problems here:
The C++ compiler in the GCC (GNU Compiler Collection) is g++, not gcc; the latter is the GNU C Compiler.
The code in main.c is a (not very good) C program and not a C++ program. C99 outlawed the implicit int return type; C++ essentially never allowed it.
Your question uses a function f; your compilation error references func. This means you did not show us exactly the code you tried to compile.
The standards say #include <stdio.h>; you should too.
#include <stdio.h>
#include "func.h"
int main()
{
double a = func(2.3);
printf("a=%f\n", a);
}
NB: This is a perfectly good C program if you work with C99. In C89, you are expected to return a value from main() rather than 'fall off the end'. C99 follows C++98 and allows falling off the end as equivalent to an explicit return 0;. I tend to put the explicit return(0); (usually with, sometimes without, the parentheses - the compilers don't mind either way) anyway. (I compile C with -Wstrict-prototypes; to get a warning-free compilation, I write int main(void), which also works with C++ but the void is not necessary there.)
The header is OK, though you will learn in due course about header guards and other paraphernalia that make headers more reliable.
#ifndef FUNC_H_INCLUDED
#define FUNC_H_INCLUDED
extern double func(double a);
#endif /* FUNC_H_INCLUDED */
The extern is not mandatory. I tend to use it, but there are many who do not.
The source file defining the function should include the header to ensure that the function definition is consistent with the declaration. All code that uses the function should include the header so that there is a prototype in scope. This cross-checking is crucial for reliability. C++ requires prototypes in scope before a function is used; it does not demand a prototype in scope before the function is defined (but it is good practice to do so). It is strongly recommended in C that you have a prototype in scope before defining an external (non-static) function. You can use -Wmissing-prototypes with C code and GCC to spot such problems, but the option is not valid for G++.
#include "func.h"
double func(double x) { return x; }
Since this is a C++ question, we could consider inlining the function in the header. Indeed, C99 also supports inline functions. However, we can ignore that for the time being.
Since this is a C++ question, we could consider that using <stdio.h> is not good because it is not type safe. You might be better off using <iostream> et al, not least because they are type safe.
#include <iostream>
#include "func.h"
int main()
{
double a = func(2.3);
std::cout << "a=" << a << std::endl;
}
The correct compilation requires both the main program and the function it invokes, so you might write:
g++ -o main main.c func.c
Or, if you are compiling it in C, then:
gcc -std=c99 -o main main.c func.c
Note that the -std=c99 is necessary to ensure that the absence of return in main() is acceptable.
Note that there are several extensions in use for C++ source code, including .C, .cpp and .cxx, all of which are accepted by G++ (as well as .c).
There are several things wrong here.
Define the function as follows in func.h
extern double func(double);
When compiling, provide all source (c, cpp) files
gcc main.c func.c -o main
You should be good to go.
Compile like this:
gcc -o main main.c func.c
Then it will be fine.
I have a question about (re-)defining functions. My goal is to have a script where I can choose to define a function or not.
Like this:
void func(){}
int main(){
if (func)func();
}
AND without the function, just:
int main(){
if (func)func();
}
Anybody an idea?
You can do this in GCC using its weak function attribute extension:
void func() __attribute__((weak)); // weak declaration must always be present
int main() {
if (func) func();
// ...
}
// optional definition:
void func() { ... }
This works even if func() is defined in another .c file or a library.
Something like this, I think. Haven't used function pointers much, so I may have gotten the syntax slightly wrong.
void func()
{
#define FUNC_PRESENT
// code
}
void (*funcptr)();
#ifdef FUNC_PRESENT
funcptr = func;
#else
funcptr = NULL;
#endif
int main()
{
if (funcptr)
funcptr();
}
Use function pointers, set them dynamically based on runtime conditions, and check for null pointers or wrap them in methods that do that check for you.
Only option in C I can think of.
In C++ you could combine templates and DLLs to dynamically define at runtime.
Really the only way that you can "choose to define a function or not" is with C preprocessor directives. For example:
#ifdef some_name
void func() {
do_whatever();
}
#else
//the else part is optional
#endif
To set these "variables" you use #define some_name
The trouble is, all of this needs to be done at compile time (before that, actually) so it can't be done with an if statement like in your example. If you want an if statement to control your program flow, just use it and don't bother with trying to rename functions or using function pointers or something.
Introduction
I guess that you are trying to do this:
Two modules, a.o and b.o
b.o contains a definition for void foo()
a.o calls void foo() only if b.o is also linked into the final executable.
This could be useful for a "plugin" system.
Variation 1
You can simulate it using function pointers. I don't know enough C to write this in proper C code, but pseudocode looks like this:
a.h
extern collectionOfFuncPtrs_t list;
int addFuncPtr();
a.c
#include "a.h"
collectionOfFuncPtrs_t list;
int addFuncPtr(FuncPtr p) {
- add func ptr to list
- return 0
}
int main() {
- loop through list of function pointers
- call functions through them
}
b.c
#include "a.h"
void bar() { /* ... */ }
static int dummy = addFuncPtr(&bar);
c.c
#include "a.h"
void ayb() { /* ... */ }
static int dummy = addFuncPtr(&ayb);
Conclusion
Now, you can link in b.o and/or c.o as you wish, and int main() will only call bar() and/or ayb() if they exist.
Variation 2
Experiment with variations on this theme if it looks like it may be useful to you. In particular, if you have only a specific number of conditionally-defined functions, you could use a bunch of individual function pointers rather than some list:
a.h
extern fptr_t bar_ptr, ayb_ptr;
a.c
#include "a.h"
int main() {
if (bar_ptr)
bar_ptr();
if (ayb_ptr)
ayb_ptr();
}
b.c
#include "a.h"
void bar() { /* ... */ }
fptr_t bar_ptr = &bar;
b_dummy.c
#include "a.h"
fptr_t bar_ptr = 0;
c.c
#include "a.h"
void ayb() { /* ... */ }
fptr_t ayb_ptr = &ayb;
c_dummy.c
#include "a.h"
fptr_t ayb_ptr = 0;
Conclusion
Now either link b.o or b_dummy.o; and either link c.o or c_dummy.o.
I hope you get the general idea, anyway...!
Bootnote
This is a lot easier in C++ where you can write a module registration system very easily with std::maps and constructors.
In C? Only by using the preprocessor as stated in other answers.
C isn't a dynamic language like, say, Python.
The right way to do what I think you're asking about in C is to use function pointers. You can take the address of a function, assign it to a variable, test it for nil, etc. However, plain old C isn't a very dynamic language; you might be better off using a different language.
if you don't mind compiler specific extension, you can use __if_exists:
#include <iostream>
using namespace std;
// uncomment the following, and it'll still work
void maybeFunc(){ cout << "running maybe" << endl; }
int main(){
cout << "hi!" << endl;
__if_exists(maybeFunc)
cout << "maybe exists!" << endl;
maybeFunc();
}
}
this works in msvc by default, and in clang if you use the -fms-extensions flag.