I have defined a structure in one of my source code files. Also I have defined pointer to that structure like (global declaration)
struct blockPropStruct
{ int random_id;
int id;
CvPoint left_up;
CvPoint right_down;
};
typedef struct blockPropStruct *newBlock;
In the same file I am assigning memory to those pointers using malloc to create array of structures.
newBlock = (blockPropStruct*)malloc(maxNum*sizeof(blockPropStruct));
Now I am trying yo use it in some other source file by declaring (global declaration)
extern struct blockPropStruct *newBlock;
Now when I use something like
newBlock[i].left_up.x=mark1[i];
It throws up an error.
It would appear that you have omitted the declaration of the struct type in the file which declares the extern variable.
The name of your structure is struct blockPropStruct. Note that in C, you can't just remove the struct part, it's part of the type's name. You can define a type for your structure so you have less typing, but I think it's better to remember to use your structures as struct blockPropStruct.
Based on the error messages you have added in your comments:
error C2036: 'blockPropStruct *' : unknown size
error C2027: use of undefined type 'blockPropStruct'
You are attempting to get the size sizeof(blockPropStruct) in your malloc() call since blockPropStruct is not a valid identifier so you are attempting to get the size of an undefined type.
To define your type:
typedef struct blockPropStruct blockPropStruct;
Now you can refer to your structure type as blockPropStruct or struct blockPropStruct.
You need to give a name with 'typedef' and point to it.
newBlock = (blockPropStruct*)malloc(maxNum*sizeof(blockPropStruct));
To actually for the above statement to work, the current source file should see the size of structure. So, check whether you have included the corresponding header file.
extern struct blockPropStruct *newBlock;
And when you are doing -
newBlock[i].left_up.x=mark1[i];
You should bring the definition of the blockPropStruct to the current compilation unit to be able to use it members. So, try -
#include "blockPropStruct.h"
extern struct blockPropStruct *newBlock; // This says to use else where
// initialized newBlock
// ....
newBlock[i].left_up.x=mark1[i]; // And to do this, bring the definition
// to this file scope
And there is no need to explicitly typecast malloc.
Related
I have a very simple question.
If I have a source code file like this:
#include<stdio.h>
#include"example.h"
struct mystructure{
//Data Variables
int a;
};
int main(){
mystructure somename;
somename.a = 1;
printf("%d\n", somename.a);
return 0;
}
With a header file like this:
#ifndef EXAMPLE_HEADER_H
#define EXAMPLE_HEADER_H
// Opaque declaration.
struct mystructure;
typedef struct mystructure mystructure;
#endif
The code will compile fine. I could also define the structure in the header file and it will compile fine.
However, if I define the structure in a different source code file and attempt to compile it with the main source code file it will keep throwing errors about forward declarations.
Is there a way to define a structure in a source code file give it a typedef in a header file and use it elsewhere in other source files?
I have been doing this awhile now by defining the structure in the header file, but I would like to know how to do this in a more opaque way.
To perform this declaration and statement
mystructure somename;
somename.a = 1;
the compiler needs to know the complete definition of the structure struct mystructure. For instance it needs to know how much memory to allocate for the object somename and whether the structure has the data member a.
So the definition of the structure must be visible in the module with main where these declaration and statement are present.
To hide the structure definition you could declare a pointer of the type struct mystructure * and call functions to initialize this pointer and data members of the pointed object. The corresponding functions must know the structure definition.
I have two files, main.c and other.h. I declare a few global variables in main.c, and most of them are fine. I can say extern whatever in other.h and access those variables. However, I defined a struct like this (in main.c):
struct LSA {
int myID;
int seqNum;
int neighborID[256];
int costs[256];
} local_LSA[256];
And when I try to access it in other.h like this
extern struct LSA local_LSA[256];
I get this error message
other.h:27:19: error: array type has incomplete element type ‘struct LSA’
extern struct LSA local_LSA[256];
I've been playing around with for a while, but... I appreciate any help anyone is able to provide!
The structure type needs to be defined before any instances of it can be created.
You need to move the struct definition into other.h before local_LSA is defined.
The header file isn't aware of the struct definition of struct LSA. What you should do instead is to declare the struct in some "lsa.h" then define and allocate the variables of that type in some .c file.
Please note that the design you suggest is spaghetti programming. There should never be a reason for another file to extern access some variable in main.c, which is the top level of your program - or otherwise your program design is flawed. Use setter/getter functions instead of spaghetti.
According to the C Standard (6.7.6.2 Array declarators)
...The element type shall not be an incomplete or function type.
In this declaration of an array within the file other.h
extern struct LSA local_LSA[256];
the element type struct LSA is incomplete type because the structure definition at this point is unknown.
So the compiler issues the corresponding error message.
other.h:27:19: error: array type has incomplete element type ‘struct LSA’
extern struct LSA local_LSA[256];
What you need is to place the structure definition in the header before the array declaration.
You could write for example in the header file other.h
struct LSA {
int myID;
int seqNum;
int neighborID[256];
int costs[256];
};
extern struct LSA local_LSA[256];
Pay attention to that this record
extern struct LSA local_LSA[256];
is a declaration of an array not a definition.
Then in main.c you could place one more declaration of the array like
struct LSA local_LSA[256];
in this case the declaration of the array will generate the so-called tentative definition of the array.
I was working with UEFI driver-related code, and I came across this:
/* EFI headers define EFI_HANDLE as a void pointer, which renders type
* checking somewhat useless. Work around this bizarre sabotage
* attempt by redefining EFI_HANDLE as a pointer to an anonymous
* structure.
*/
#define EFI_HANDLE STUPID_EFI_HANDLE
#include <ipxe/efi/Uefi/UefiBaseType.h>
#undef EFI_HANDLE
typedef struct {} *EFI_HANDLE;
The full source code is in this path
http://dox.ipxe.org/include_2ipxe_2efi_2efi_8h_source.html
This is my first encounter with anonymous structure, and I couldn't make out the logic of redefining a void * to a pointer to an anonymous structure. What kind of a hack the "bizzare sabotage attempt" hints at?
The library is using information hiding on the internal data object behind the address held in an EFI_HANDLE. But in doing so, they're making the code more susceptible to accidental bugs.
In C, void* is transparently cast to any other non-void* non-const data pointer type without warning (it's by language design).
Using a non-void pointer type ensures an EFI_HANDLE is only used where EFI_HANDLE belongs. The compiler's type-checking kicks you in the groin when you pass it somewhere else that isn't EFI_HANDLE , but rather a pointer to something else.
Ex: As void*, this will compile without warning or error
#include <string.h>
#define EFI_HANDLE void*
int main()
{
EFI_HANDLE handle = NULL;
strcpy(handle, "Something");
}
Changing the alias to:
typedef struct {} *EFI_HANDLE;
will reap the ensuing "incompatible pointer type" compile-time error.
Finally, as an anonymous struct, there is no pointless structure tag name adding to the already-polluted name space that you can use (accidently or nefariously).
That isn't an anonymous structure, but a struct without a tag.
An anonymous structure can only exist as a member of another struct,
and it must also not have a tag1.
Defining a struct without any members is not allowed. The code you're looking at is using a compiler extension that permits this.
The library is doing this to hide the definition of the structure from the user, while maintaining type safety.
However there is a much better way to do this. If you have a hidden structure definition, you can still define an opaque pointer to it, that has a type, so it is type safe:
struct hidden //defined in a file and not exposed
{
int a;
};
void Hidden( struct hidden* );
void Other( struct other* );
struct hidden* a = NULL; //doesn't see the definition of struct hidden
Hidden( a ); //it may be used
Other( a ); //compiler error
1 (Quoted from: ISO/IEC 9899:201x 6.7.2.1 Structure and union specifiers 13)
An unnamed member whose type specifier is a structure specifier with no tag is called an
anonymous structure; an unnamed member whose type specifier is a union specifier with
no tag is called an anonymous union. The members of an anonymous structure or union
are considered to be members of the containing structure or union. This applies
recursively if the containing structure or union is also anonymous
Take the example of structure defined for a linked list...
struct test_struct line 1
{ line 2
int val; line 3
struct test_struct *next; line 4
}; line 5
At line 4, since test_struct is not even fully defined (I am assuming structure is fully defined at line 5 because of ';', before that we cannot say structure is defined) then how come we don't get error at line 4 that test_struct is not defined...?
It's true that the struct test_struct is not fully defined before the closing ;, at line4 you are only defining a pointer to an incomplete type, which is fine.
To define a complete object of type struct test_struct, compiler needs to know the complete information about that object. But to define a pointer to some type, it's not needed.
For example, you can't do:
struct test_struct
{
int val;
struct test_struct value;
};
because to define value, the complete information about the object's type is needed. But to define struct test_struct*, it's not required.
In your example you define a self reference structure. A self reference structure contains one or more pointer(s) to itself (as you define in line 4)! Self referenced structures usually need to be handled using dynamic memory handle subroutines like free and malloc. In your case you just define a pointer to a type which handled in time when your file has been complete. At compile time, C compiler calculates memory bytes which your pointers need to point that and at that time your structure has been defined exactly.
I have something like:
typedef struct Data DATA, *DATA_PTR;
typedef struct Units UNITS, *UNITS_PTR;
struct Data
{
double miscData;
UNITS units;
};
struct Units
{
double x[2];
double y[2];
double z[2];
};
in my project_typedef.h file.
In another file, I have something like:
void fileInput(DATA_PTR data)
{
//usual declarations and other things
data->miscData = 0; //Works!
data->units.x[0] = 5; //Doesn't work
//etc...
}
However, this doesn't work since units is declared after data in project_typedef.h (if I switch the order it works). The error that i get is "left of '.x' must have struct/union type". I thought that the forward declaration would fix this issue. Why not?
When you define Data, all members must be complete types. Since UNITS isn't a complete type at that point, this doesn't work. (By contrast, UNITS_PTR would be fine, since pointers to incomplete types are complete types.)
Simply put the Units definition above the Data definition and you should be fine.
(As #cnicutar already noted, you're also using the array x wrong.)
The forward declaration allows you to use its name in context where an incomplete type is allowed. Declaring a struct member is not one of such cases, the complete definition must be known as it contributes to the struct layout.
for a struct definition you should always use complete types for all members in a structure... but this is not the case with UNITS units in struct Data,which declares a variable named units of type struct Units which is never declared before the struct Data... this reflects an error.. you should place the Units definition above Data definition.. and all will work fine..
and regarding forward declaration this does not work since whenever a struct variable is defined, the compiler first allocates the memory required to the struct (struct members donot have a memory allocated to them, unless they are linked to a struct type of variable.. thats why struct variables cant be initialized inside struct template).. :)
There is no prototype for struct. This is because compiler needs to know size of struct before using it. You could use pointer on struct, because pointers have known size no matter which type they point to.