C compiling - "undefined reference to"? - c

I am making a reliable data transfer protocol and have the function prototype
void tolayer5(int, char data[]);
With the structs
struct msg {
char data[20];
};
struct pkt {
int seqnum;
int acknum;
int checksum;
char payload[20];
};
And when I call the function in this format:
tolayer5(A, packet.payload);
Where A is an int and packet.payload is a struct pkt, I get the error "undefined reference to 'tolayer5(int, char*)'. Can you help me see what I'm missing here?
void tolayer5(int AorB, char data[])
{
int i;
if (TRACE>2)
{
printf("TOLAYER5: data received:");
for (i=0; i<20; i++)
printf("%c",data[i]);
printf("\n");
}
}
Thank you all for helping with the original issue! :) When trying to fix that one, however, I ran into an infinite loop that I think has something to do with me addressing characters in an array incorrectly (it's been awhile since I've done C like this. Can you help me to find where I'm creating an infinite loop?
I have updated the above code to what I'm now working with. Notice the main changes have been to my function:
void tolayer5(int AorB, char data[])
And this line inside the function: printf("%c",msgReceived.data[i]); since now it's just:
printf("%c",data[i]);

seems you need to link with the obj file that implements tolayer5()
Update:
your function declaration doesn't match the implementation:
void tolayer5(int AorB, struct msg msgReceived)
void tolayer5(int, char data[])
So compiler would treat them as two different functions (you are using c++). and it cannot find the implementation for the one you called in main().

Make sure your declare the tolayer5 function as a prototype, or define the full function definition, earlier in the file where you use it.

As stated by a few others, this is a linking error. The section of code where this function is being called doesn't know what this function is. It either needs to be declared in a header file an defined in its own source file, or defined or declared in the same source file, above where it's being called.
Edit: In older versions of C, C89/C90, function declarations weren't actually required. So, you could just add the definition anywhere in the file in which you're using the function, even after the call and the compiler would infer the declaration. For example,
int main()
{
int a = func();
}
int func()
{
return 1;
}
However, this isn't good practice today and most languages, C++ for example, won't allow it. One way to get away with defining the function in the same source file in which you're using it, is to declare it at the beginning of the file. So, the previous example would look like this instead.
int func();
int main()
{
int a = func();
}
int func()
{
return 1;
}

Related

Pointers + structs + functions in C identifier undefined

So this is my code and I don't understand why I get that identifier "pers" is undefined, when I'm clearly pointing at it from another function, which is as far as I know, the utility of pointers.
I've gone through some research but nothing seemed to solve my issue since I'm dealing with structs and all that.
Also one of the requirements is that tle so called "leer_persona();" cant have any value in the parenthesis
#include <stdio.h>
typedef struct{
int num;
char letra;
}tdni;
typedef struct{
char nom[20];
tdni dni;
}tpersona;
tpersona leer_persona();
void mostrar_persona(tpersona p);
int main(){
tpersona pers;
pers = leer_persona();
mostrar_persona(pers);
return 0;
}
tpersona leer_persona(){
int i=0;
int *fp;
fp = &pers;
Thanks.
Pers has function scope in "main()". It is not visible outside of "main()".
https://www.geeksforgeeks.org/scope-rules-in-c/
Function scope begins at the opening of the function and ends with the
closing of it.
See this link for more details: C - Scope Rules
If you want to use "pers" in another function, you'd typically pass it as a function parameter, e.g. tpersona leer_persona(tpersona * pers). In this example, I passed parameter "pers" by reference, instead of copying by value.

How to declare global variable for an anonymous structure in C?

I am using Pelles C on Windows 8.1.
How to declare single global variable for a structure in C?
Code 1: it works but I do not want any other object of the same type to be created. If code 2 has problems then I will have to use this one.
Single.h
struct single{
int x;
};
extern struct single oneAndOnly;
void initSingle(void);
void printSingle(void);
Single.c
#include <stdio.h>
#include "Single.h"
struct single oneAndOnly;
void initSingle(void){
oneAndOnly.x = 10;
}
void printSingle(void){
printf("x = %d\n",oneAndOnly.x);
}
Main.c
#include "Single.h"
int main()
{
initSingle();
printSingle();
return 0;
}
Code 2: It works but I am not clear about the combination of declaring and defining a variable in a header file. Will it cause a problem? I get no error though.
Single.h
struct{
int x;
}oneAndOnly;
void initSingle(void);
void printSingle(void);
Single.c
#include <stdio.h>
#include "Single.h"
void initSingle(void){
oneAndOnly.x = 10;
}
void printSingle(void){
printf("x = %d\n",oneAndOnly.x);
}
Main.c is the same as in Code 1.
Can I use code 2 without any problem?
Can someone tell me why does code 2 work, when I and many others thought that it would not?
Thanks to everyone for all your comments and ideas and answers
There is a third variant which might be of interest.
It "hides" the struct single completely in Single.c. Hence, no accidental access is possible.
Single.h:
void initSingle(void);
void printSingle(void);
Single.c:
#include <stdio.h>
#include "Single.h"
struct Single {
int x;
};
static struct Single oneAndOnly;
void initSingle(void)
{
oneAndOnly.x = 10;
}
void printSingle(void)
{
printf("x = %d\n", oneAndOnly.x);
}
main.c:
#include "Single.h"
int main()
{
initSingle();
printSingle();
return 0;
}
Live Demo on Wandbox
Actually, this approach is similar to P__J__'s answer. I just was too slow to press the Send button.
I needed some time to realize that the solution in quest should prevent an (accidental) second variable of the type of oneAndOnly.
"Hiding" the struct in the C file with a static instance is probably the best one can have in C. Even the counter examples in melpomene's answer shouldn't work in this case.
If read/write access to the single instance is required, I would add something like "getter"/"setter" functions.
This reminded me to the Singleton pattern though I'm not sure if that is a legal usage for a non-OO language like C. Googling a bit, I found (as well) How to create a Singleton in C? which I find worth to mention.
I googled a bit concerning the actual question of OP whether her/his Code 2 is valid as well. I suspected something like a duplicated definition (may be, because I did too long in C++ in daily work).
Actually, I tried OP's Code 2 in Wandbox – no duplicate definition issue. Finally, I found Are the global variables extern by default or it is equivalent to declaring variable with extern in global? and came to the conclusion that Code 2 should be fine as well.
The limitation is that Code 2 allows only default initialization (filling with 0s if I remember right). As soon as an initializer is added, the compiler complains (as expected) as it's included multiple times.
You call the function in other compilation unit. It uses the global variable not your main program. So you do not even have to know the data structure and the variable, as you newer use any of them in your main program.
you can reduce it to :
void initSingle(void);
void printSingle(void);
int main()
{
initSingle();
printSingle();
return 0;
}
and
#include <stdio.h>
struct{
int x;
}oneAndOnly;
static struct single oneAndOnly;
void initSingle(void){
oneAndOnly.x = 10;
}
void printSingle(void){
printf("x = %d\n",oneAndOnly.x);
}
None of your attempts will work in practice.
With e.g. gcc or clang I can just do
typeof(oneAndOnly) secondInstance;
gcc also supports
__auto_type secondInstance = oneAndOnly;
(not sure about clang).
Even if the compiler in question doesn't support these extensions, I can just copy/paste the anonymous struct declaration from the header.
That said, I don't see what preventing other objects of the same type buys you. It makes sense in Java to make the constructor private because a constructor has behavior whose use you may want to restrict, but in C structs are just dumb collections of data.

Not getting correct value in structure

might be it's silly question but not getting what is wrong in my code.
I am writing simple command parser in which it will initialize appropriate parameters and call appropriate functions related to command code.
Ex.
char buffer[]="1123,13,46";
In above line 1123 is command code and rest of two tokens are parameters. In parser it will first find command code form command table and if command found then it will initialize structure of that command with above parameters.
Currently in my code i am successfully fetching correct command from command table and call that command's functions but failed to initialize the parameters with above values (13 and 46 here).Always getting 0.
As per below code same thing i want in my command parser but little modification
typedef struct
{
void *fields[2];
}tmpStruct;
typedef struct
{
int x;
int y;
}myStruct;
tmpStruct tmp_struct;
myStruct *getParams(tmpStruct *t_struct)
{
myStruct *genericStruct = malloc(sizeof(myStruct));
//setup the order of the fields in the handler
t_struct->fields[0]=(void*)&genericStruct->x;
t_struct->fields[1]=(void*)&genericStruct->y;
return genericStruct;
}
void *fillValue(tmpStruct *t_struct)
{
void *genericStruct;
genericStruct = getParams(t_struct);
*((int*)t_struct->fields[0])=12;
*((int*)t_struct->fields[1])=13;
return genericStruct;
}
void pritValue(myStruct *my_struct)
{
printf("%d %d\n",my_struct->x,my_struct->y);
}
int main()
{
void *genericStruct;
genericStruct = fillValue(&tmp_struct);
pritValue(genericStruct);
return 0;
}
Please find my working source file here
And header file here
The problem is that you are casting function pointers to types of functions that take different parameter types. Trying to make calls to functions through pointers like that is undefined behavior. Although you could potentially get away with calls that are similar - say, return myStruct* in place of void* pointer (although it's still undefined behavior), there is no way you could cast a function that takes an int and a myStruct* to a function type that takes an int and a variable list of arguments.
Changing your functions to the correct signatures to match cmdTableStruct table fixes this problem:
void *setParams(paramHandler_type *pHandler);
int printParams(int commandType,... );
static cmdTableStruct cmdTable[]=
{
{ 1123,setParams,printParams },
//more command in same manner
};
Demo.
Of course now you need to handle parameters from the ... list individually using the functionality from the <stdarg.h> header.
Also, the way you dereference param handler when assigning values is incorrect - the index should be applied to paramValue, not to pHandler:
*((int*)pHandler->paramValue[j]) = (int)atoi(token);

How to correctly assign function pointers to elements of typedef struct

Here I provide the concrete example nevertheless. I have a typedef (from a header file maplec.h defining OpenMaple).
typedef struct {
void (M_DECL *textCallBack) ( void *data, int tag, char *output );
void (M_DECL *errorCallBack) ( void *data, M_INT offset, char *msg );
...
} MCallBackVectorDesc, *MCallBackVector;
In my code I want to assign the callback functions to use. In the examples from the manual (http://www.maplesoft.com/applications/view.aspx?SID=4383&view=html) this is done with
MCallBackVectorDesc cb = { textCallBack,
0, /* errorCallBack not used */
...
};
However I want to keep a reference to this variable cb in a structure which I defined as
struct open_maple {
MCallBackVectorDesc *call_back_vector;
};
Then I initialize with
open_maple->call_back_vector = (MCallBackVectorDesc *)malloc((size_t)sizeof(MCallBackVectorDesc));
(open_maple->call_back_vector)->textCallBack = &textCallBack;
(open_maple->call_back_vector)->errorCallBack = 0;
This code does not produce any compiler warnings nor Segfaults, but I do not seem to receive any calls of textCallBack either, while the online example version would work. I tried other definitions and assignments, but always got warnings or Segfaults.
It boils down to the question: How do I correctly assign the pointers to the callback functions collected in the typedef struct if I do not want to assign them at initialization (in the declaration of the variable cb)?
Edit 1
It has been suggested below that the error occurs because I am referencing the textCallBack function as &textCallBack function which generates a pointer from a pointer. However the example works neither with nor without the &. Note also that the following code works:
/* some standard libraries */
#include <stdlib.h>
#include <stdio.h>
void function(void){
printf("IAMHERE\n");
};
int main()
{
void (*myfunction)(void) = &function;
myfunction();
return 0;
}
I am using gcc -o test test.c to compile it.
Edit 2
Some more investigations showed that the problem is supposedly related to my use of OpenMaple.
textCallBack is defined as a pointer to function.
You're taking the address of it -- pointer to pointer to function.
Is that really what you intend to store into your structure?

Polymorphism in C

I'm designing a program in C that manipulates geometric figures and it would be very convenient if every type of figure could be manipulated by the same primitives.
How can I do this in C?
You generally do it with function pointers. In other words, simple structures that hold both the data and pointers to functions which manipulate that data. We were doing that sort of stuff years before Bjarne S came onto the scene.
So, for example, in a communications class, you would have an open, read, write and close call which would be maintained as four function pointers in the structure, alongside the data for an object, something like:
typedef struct {
int (*open)(void *self, char *fspec);
int (*close)(void *self);
int (*read)(void *self, void *buff, size_t max_sz, size_t *p_act_sz);
int (*write)(void *self, void *buff, size_t max_sz, size_t *p_act_sz);
// And the data for the object goes here.
} tCommsClass;
tCommsClass commRs232;
commRs232.open = &rs232Open;
: :
commRs232.write = &rs232Write;
tCommsClass commTcp;
commTcp.open = &tcpOpen;
: :
commTcp.write = &tcpWrite;
The initialisation of those function pointers would actually be in a "constructor" such as rs232Init(tCommClass*), which would be responsible for setting up the default state of that particular object to match a specific class.
When you 'inherit' from that class, you just change the pointers to point to your own functions. Everyone that called those functions would do it through the function pointers, giving you your polymorphism:
int stat = (commTcp.open)(commTcp, "bigiron.box.com:5000");
Sort of like a manually configured vtable, in C++ parlance.
You could even have virtual classes by setting the pointers to NULL -the behaviour would be slightly different to C++ inasmuch as you would probably get a core dump at run-time rather than an error at compile time.
Here's a piece of sample code that demonstrates it:
#include <stdio.h>
// The top-level class.
typedef struct _tCommClass {
int (*open)(struct _tCommClass *self, char *fspec);
} tCommClass;
// Function for the TCP class.
static int tcpOpen (tCommClass *tcp, char *fspec) {
printf ("Opening TCP: %s\n", fspec);
return 0;
}
static int tcpInit (tCommClass *tcp) {
tcp->open = &tcpOpen;
return 0;
}
// Function for the HTML class.
static int htmlOpen (tCommClass *html, char *fspec) {
printf ("Opening HTML: %s\n", fspec);
return 0;
}
static int htmlInit (tCommClass *html) {
html->open = &htmlOpen;
return 0;
}
// Test program.
int main (void) {
int status;
tCommClass commTcp, commHtml;
// Same base class but initialized to different sub-classes.
tcpInit (&commTcp);
htmlInit (&commHtml);
// Called in exactly the same manner.
status = (commTcp.open)(&commTcp, "bigiron.box.com:5000");
status = (commHtml.open)(&commHtml, "http://www.microsoft.com");
return 0;
}
This produces the output:
Opening TCP: bigiron.box.com:5000
Opening HTML: http://www.microsoft.com
so you can see that the different functions are being called, depending on the sub-class.
I'm astonished, does no one have mentioned glib, gtk and the GObject system.
So instead of baking yet-another-oo-layer-upon-C. Why not use something that has proofed to work?
Regards
Friedrich
People have done silly things with various types of structs and relying on predictable padding - for example you can define a struct with a particular subset of another struct and it'll usually work. See below (code stolen from Wikipedia):
struct ifoo_version_42 {
long x, y, z;
char *name;
long a, b, c;
};
struct ifoo_old_stub {
long x, y;
};
void operate_on_ifoo(struct ifoo_version_42 *);
struct ifoo_old_stub s;
...
operate_on_ifoo(&s);
In this example, the ifoo_old_stub could be considered a superclass. As you can probably figure out, this relies on the fact that the same compiler will pad the two structs equivalently, and trying to access the x and y of a version-42 will work even if you pass a stub. This ought to work in the reverse as well. But AFAIK it doesn't necessarily work across compilers, so be careful if you want to send a struct of this format over the network, or save it in a file, or call a library function with one.
There's a reason polymorphism in C++ is pretty complicated to implement... (vtables, etc)

Resources