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.
Related
I have learned a decent amount of java and now I want to learn C, I've learned a little about structs and typedefs but I have errors when I place the typedef after the main() function and it is used from within the main() function.
Is there a way to declare types but not define them in C so I can keep my code after the main() function similar to functions? (I'm not sure if this is good practice but I like organizing my code this way)
Don't do that. C code is intended to be read by the compiler and it will learn about new definitions as it keeps reading the file. Moving things below main() serves no purpose. It will also confuse other humans.
As for the question itself: in some cases, yes, you can. If everything you need is a forward declaration, you can do so. But in most cases you will want the definition, so it won't help you.
For example, this will compile:
struct T;
int main(void)
{
struct T * p = 0;
return !!p;
}
// Later on you may define `struct T`
C requires a type to be declared before it's used. If the code is just using a pointer to the type then the code doesn't not need to declare the members, this is a forward declaration. Other usage, such as passing the type by value or using it as a local variable requires a full definition.
C projects generally use headers which will provide the definition of types. These are included into the C modules.
// header.h
#ifndef _header_h_
#define _header_h_
struct DescribedType {
int member;
char* variables;
};
#endif
// module.c
#include "header.h"
struct ForwardDeclaration;
ForwardDeclaration* allocForward();
int main(){
DescribedType someType;
ForwardDeclaration* someValue = allocForward();
return 0;
}
struct ForwardDeclaration {
int declaredLater;
};
please....
I am trying to make library which is intended like a lib based on struct
I wanna reach something like "mats.basic.add(1,1);"
first error when build is first line inside struct (both of them) and then
are, although editors hints me after dot operation like add or sub
next errors are "uknown members add, sub
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
typedef uint8_t (*p_fn1)(uint8_t,uint8_t);
uint8_t fn_add(uint8_t num1,uint8_t num2){
return num1+num2;
}
uint8_t fn_sub(uint8_t num1,uint8_t num2){
return num1-num2;
}
typedef struct mats {
p_fn1 add=fn_add;
p_fn1 sub=fn_sub;
}mats;
void init_mats(mats* t_mats){
t_mats->add=fn_add;
t_mats->sub=fn_sub;
}
int main()
{
mats mats_s;
init_mats(&mats_s);
uint8_t c=mats_s.add(1,1);
printf("%d",c);
return 0;
}
thanks a lot
You're attempting to initialize struct members when you define the struct. That's invalid syntax.
Remove those initializers from the definition.
typedef struct mats {
p_fn1 add;
p_fn1 sub;
}mats;
If you want to have methods that can be called on your types, write your program in C++. It has that feature; C does not.
There isn't any way to do this in pure C that won't be clumsy to write, slow to run, and/or use inappropriate amounts of memory. The specific way that you're trying doesn't work at all because you're trying to set fields on a type, rather than on an instance of that type, but even if you fixed that, you'd still run into some other fundamental limitations of the language.
I want to write data to an array of structures. The structure itself is declared and defined inside main(). I have 3 functions that need to write, process and read the data from the array.
All I could achieve was creating a global struct declaration and then passing pointers to them.
Is it possible without making the structure declaration global?
The relevant code is posted below.
This is my struct declaration outside of main()
struct date
{
int d;
int m;
int y;
};
struct stud
{
int roll;
char name[30];
struct date dob;
int P;
int C;
int M;
float PCM;
char flag_in;
char flag_pro;
};
These are the function defintions.
void getdata(struct stud *S)
{
scanf("%d", &(S->roll));
scanf("%s", (S->name));
//Similarly for dob, p, c, m
(S->flag_in)='1';
return;
}
void process(struct stud *S)
{
if(S->flag_in=='1')
{
S->PCM=(S->P + S->C + S->M)/3;
S->flag_pro='1';
}
}
void display(struct stud *S)
{
for(int x=0; x<10; x++)
if(S[x].flag_in=='1')
{
//printing the data to the console output
}
}
These are the function calls:
getdata(&S[i]);
process(&S[x]);
display(S);
It's entirely valid to not want to expose other parts of your program to the internal structure of a type.
C is extremely well placed to do this with considerable elegance.
Call this X.h
//Declaration of X as pointing to an incomplete struct XS.
//This says there's such a thing as a struct XS but not how it is laid out or even how big it is.
//It also says X is a short-hand for a pointer to a mysterious XS structure.
typedef struct XS* X;
//Creates an X and returns a pointer to it. Remember to call destroyX(.) exactly once - later.
X createX(void);
//Does something with X and returns some number.
int doXThing(X x);
//Destroys an X. Must be called exactly once for each return value from createX().
void destroyX(X x);
This is prog.c (containing your main(.) function).
#include <stdlib.h>
#include <stdio.h>
#include "X.h"
//Now we actually define that mysterious structure.
//Other translation units will not see this.
struct XS {
int v;
} ;
//Here we have size and layout so we can actually implement it.
X createX(void){
X x=malloc(sizeof(struct XS));//Explicit allocation of 'implementation struct'.
if(x==NULL){
return NULL;//malloc(.) failed.
}
x->v=0;
return x;
}
int doXThing(X x){
return (x->v)++;
}
void destroyX(X x){
free(x);
}
int main(void) {
X x=createX();
printf("%d\n",doXThing(x));
printf("%d\n",doXThing(x));
printf("%d\n",doXThing(x));
destroyX(x);
return 0;
}
Notice that the other modules using #include "X.h" don't see the layout of the structures.
The upside is the implementation can change normally without recompilation - just re-linking.
The downside is that without access to the size and layout of X those 'using' modules need to delegate all the work to a module that does!
That means all Xs have to come of the free-store (or a static pool inside the implementing module..).
This model is really rather common and quite powerful as it allows for complete abstraction and data hiding.
If you're willing to do a load of casting you don't even need to 'reveal' the name XS.
typedef XSHandle* X;
Or even
typedef unsigned short* X; //Little used type... Illegal but works on most platforms - check your documentation of use char (bare, signed or unsigned).
But don't get led into:
typedef void* X;
In C. void* is so promiscuous in its casting you will get into trouble!
C++ however behaves far better about that.
PS: It's not normal to put the implementation in the same translation unit as main(.).
It's not wrong in a small project but it's not normal to get into quite so much abstraction in a small project.
PPS: A stated this method provides for a very high degree of OO programming. It may be of interest that Stroustrup made documented design decisions to NOT do this for all classes in C++ because it has a fixed and unavoidable overhead and he gave himself a 'zero-overhead principle' and wanted to provide a way of 'mixing' abstraction with direct access to object layout (allocation as local variable, direct access to members, inline functions,...).
I think he made the right decision as a language level decision for the intended use of C++. That doesn't make it a bad design pattern where appropriate.
What you could do is declare the struct inside the main. and pass the pointer when the functions are called:
//this code is inside main
struct stud arr[10]; // create an array for the struct
display(arr); //pass the pointer to function
since the main is called before the functions the data will not be deleted and will exist on the processing of other functions which can pass the pointer between them.
Although I suggest not to use this method if the functions are not for one purpose (change value, print, etc...). If the data struct is used as global declare it as global.
I have the impression that you are not clear on the difference between the definition of a struct type and an instance of that type.
To be able to work with a struct variable, your functions have to see the full type declaration, such that the compiler knows how the variable is structured and to access the different fields. But there is no need that they see the variable declaration as such. The variable can be accessed without problems through a pointer that you pass as argument.
If you have your structure within the main() then the scope of this structure is local to main()
Since structures are user-defined data-types it can't used as you try because this new type is just visible within the main()
So the functions which you have defined will not have visibility of the structure.
So in order to handle this the structure should be made global.
So a binary answer to your question
Is it possible without making the structure declaration global?
is NO
Is it possible without making the structure declaration global?
No, any functions needs a struct's definition to be visible (globally) for it to be useable. Otherwise, from the function's viewpoint, the invisible struct would be an undefined identifier.
Local structs will not be visible anywhere outside the function.
The more important question would be what do you save in making it local as opposed to global? One thing that comes to my mind is that compilation time might be faster since if declared global in a header where lot of TUs see it unnecessarily.
I'm making an ncurses application, and I've come accross something that's puzzling.
If you have a struct with a member named "refresh" that is a function pointer, and you call that function later, you will get the following compile-time error:
main.c:20:10: error: ‘Point’ has no member named ‘wrefresh’
point.refresh();
Here's a little test you can try to compile:
#include <ncurses.h>
typedef struct PointStruct Point;
void Point_refresh() {
}
struct PointStruct {
int x;
int y;
void (*refresh)();
};
int main() {
Point point;
point.x = 0;
point.y = 0;
point.refresh = &Point_refresh;
point.refresh();
}
That will give you the error mentioned above. However, if you take out the first line that includes ncurses, it will compile with no issues.
What is the reason that this does not work with ncurses, and is there a way around it? It's not really a big deal, just a slight annoyance that I have to rename that member.
Because refresh() is a "pseudo-function" #defined by curses as a macro for wrefresh(win), so the preprocessor is going to replace all occurrences of that word in your source. There's no sensible way round it other to #undef it, and always use wrefresh() instead.
Replace:
point.refresh();
With:
(point.refresh)();
I am not sure that what I am trying to do is called encapsulation, but it's an OOP concept. I am implementing a binary tree and in particular the insert function:
typedef struct __node* tree;
typedef struct __node { void* data; tree l,r; } node;
typedef struct {int (*cmp)(void* a,void* b); tree root;} avl_tree;
....
void tree_insert(tree node, tree* root, int (*cmp)(void* a,void* b))
{
if (*root==NULL) { *root=node; return; }
int c1 = cmp(node->data, (*root)->data);
if (c1==-1) tree_insert(node, &((*root)->l), cmp);
}
tree tree_new_node(void*data){ tree a = malloc(...); ... return a; }
void avl_insert(void* data, avl_tree* a)
{
tree_insert(tree_new_node(data), &(a->root), a->cmp);
....
}
The module is to be used through the avl_insert function which is given a pointer to the relevant balanced tree avl_tree which contains the pointer to the raw tree as well as a pointer to comparator. Now, it should obviously call tree insert and tree_insert should have access to the comparator as well as to the node I am currently inserting. The function walks on a binary tree so it's naturally recursive. However, if I give it the comparator and the current node as parameters they will be passed with each recursive invocation which is not necessary since they will always be the same.
I would like to avoid having to do so. I have not been able to come up with a clean and nice solution. These are the options that I could think of:
Use a C++ class and have the tree_insert function be a method of avl_tree class. Then it would have access to the comparator through the this pointer. The problem with this solution is that I want to use C not C++. Besides, it won't eliminate the passing of the current node parameter.
Use static members inside the function (or global data). I am not sure I can cleanly initialize them at each avl_insert call. Besides, this solution is not thread safe.
Now that I think about it this seems very easy to implement in a functional programming language. I wonder, is this a fundamental problem with C or is it just me not knowing how to do it. What would be the cleanest way to achieve this?
Thank you!
After I thought about Victor Sorokin's answer I read about the this pointer and it turns out it is an implicit parameter in every member function call. Now that I think about it it seems the only logical solution. Each invocation of the tree_insert function needs to know the address of the structure it's operating on. Not even in a functional language could you avoid that extra pointer...
A possible solution would be to keep a pointer to the main tree structure in each node..
So it's a fundamental "problem".
One fun approach that could be used to achieve encapsulation is looking into assembly code emitted by C++ compiler and then translating it into appropriate C code.
Another, more conventional, approach would be to use some C object library, like GLib.
I think, though, these two methods will give similar results :)
By the way, first option you mentioned is just as vulnerable to threading issues as second. There's no implicit thread-safety in C++.
"OOP" C code I have seen in Linux kernel (file-system layer) is mostly concerned with polymorphism, not with encapsulation. Polymorphism is achieved by introducing structure enumerating possible operations (as pointers to functions). Various "subclasses" then created, each initializing this structure with it's own set of implementation methods.
You should be able to convert that tail recursion to iteration, and avoid the function calls altogether. Something like
void tree_insert(tree node,tree*root,int (*cmp)(void*a,void*b))
{
tree* current = root;
while (*current != NULL)
{
int c1=cmp(node->data,(*current)->data);
if(c1==-1)current = &((*current)->l);
else current = &((*current)->r);
}
*current=node;
}
There is already a question covering my answer—What does “static” mean in a C program?
You can roughly take a C source file as a class. The keyword static makes the variable or function have only internal linkage, which is similar to private in classical OOP.
foo.h
#ifndef FOO_H
#define FOO_H
double publicStuff;
double getter (void);
void setter (double);
int publicFunction (void);
#endif
foo.c
#include "foo.h"
static double privateStuff;
static int privateFunction (void)
{
return privateStuff;
}
int publicFunction (void)
{
return privateFunction();
}
double getter (void)
{
return privateStuff;
}
void setter (double foo)
{
privateStuff = foo;
}
main.c
#include "foo.h"
#include <stdio.h>
static double privateStuff = 42;
static int privateFunction (void)
{
return privateStuff;
}
int main (void)
{
publicStuff = 3.14;
setter(publicStuff);
printf("%g %d %d\n", getter(), publicFunction(), privateFunction());
return 0;
}