I can check non-struct types,but when checking struct,always getting a "Function "struct" not defined.":
(gdb) l ngx_http_request_t
10
11 #include <ngx_config.h>
12 #include <ngx_core.h>
13
14
15 typedef struct ngx_http_request_s ngx_http_request_t;
16 typedef struct ngx_http_upstream_s ngx_http_upstream_t;
17 typedef struct ngx_http_cache_s ngx_http_cache_t;
18 typedef struct ngx_http_file_cache_s ngx_http_file_cache_t;
19 typedef struct ngx_http_log_ctx_s ngx_http_log_ctx_t;
(gdb) l struct ngx_http_request_s
Function "struct" not defined.
Is it possible in gdb?
Try ptype ngx_http_request_t
l is usually used with a line number to view a particular line of code, although it can be used with a function name.
Because struct is not a line number or a function name, you can not view its definition.
What type of output are you expecting?
It looks like you really want the values of the data in the struct, meaning you have to create a struct of that type first.
You can print the value of the variable declared with that type:
ngx_http_request_t foo;
(gdb) print foo
Related
This question already has answers here:
What is the use of Struct Tag name in C programming?
(3 answers)
What are the advantages of differentiating type/tag names for a typedef in C?
(3 answers)
Does typedef of a structure without tag creates distinct type each time it is used and if not why?
(2 answers)
Closed 6 months ago.
In the following code, I thought saCmdQueue_s is a struct and saCmdQueue_t is an object of type saCmdQueue_s. But then I see the last line looks like they are using saCmdQueue_t to set the type for an object named sa_queue[SA_QSIZE]. Can some help me understand.
typedef struct saCmdQueue_s {
uint8_t *buf;
int len;
} saCmdQueue_t;
#define SA_QSIZE 6 // 1 heartbeat (GetSettings) + 2 commands + 1 slack
static saCmdQueue_t sa_queue[SA_QSIZE];
In C++, when struct is declared, usage is different according to declare type.
If struct is declared as typedef type, you can write other name at the end of struct. Other name is the new name of the type - struct you declared.
Otherwise, if struct is declared as usual type, the result is the following.
struct saCmdQueue_s {
uint8_t* buf;
int len;
} saCmdQueue_t;
#define SA_QSIZE 6 // 1 heartbeat (GetSettings) + 2 commands + 1 slack
saCmdQueue_t sa_queue[SA_QSIZE];
Error: variable "saCmdQueue_t" is not a type name
If you write typedef in front of struct, the struct is declared the type like data type(int, char, string, vector, ...).
If you want to declare an int you do for instance
int x;
You could after assign a value to x (or "define" x) for instance as follows :
x = 3;
Of course, you could have done directly
int x = 3;
There are types whose variables should be declared and defined at the same time, for instance
const double y = 2.3;
as well as type whose variables you simply can't declare and define at the same time, for instance a pointer to an array of three char's :
typedef char (*pc3)[3];
char c3[3] = "ok";
pc3 apc3 = &c3;
(Am I wrong on the two previous examples ? Is there a one-liner (only one semi-column allowed) for the last one ?)
Consider now the following function pointer definition :
typedef int (*ipfunci)(int);
ipfunci fptr = &f; // where f is some int -> int function
(no one-liner for this as far as I know). Perfectly legal of course, but what about
typedef int (ifunci)(int);
Perfectly legal as well, but you can't define a variable of "type" 'ifunci' after having declared it, and what's it's use ?
This boils down to my real question : looking at
typedef char (*pc3)[3];
typedef int (*ipfunci)(int);
one sees an analogy between the two definitions, if one decides to see a size 3 array of char's as a function
0 -> char
1 -> char
2 -> char
One could also see
typedef int * pi ;
as the definition of the "type" pi as constant function with value equal to an int.
How far does this synthactic and functional analogy go ? What is behind types whose definitions really require a typedef : are they systematically "functional" types ?
What is the meaning of the struct variable's name?
In other words, when i tried code :
typedef struct enr
{
int a ;
char b ;
}enr ;
int main()
{
enr x ;
printf(" x = %d\n",x) ;
printf(" x.a = %d\n",x.a);
return 0 ;
}
I get : 38 for x and a.x both ! so I get the first field of the structure as a content of x.
Can any one tell me what's happen in the general case (when the first variable was an array, char, or something else)?
enr is never initialized in your code, so the values of a and b are whatever happened to be in the memory before the object was constructed there. To fix this, use
enr x = {1, 'a'};
You get 38 in both case, because your struct is a POD - plain old data. Therefore, there is nothing more to you struct than an int and a char together. Because C++ does not reorder struct elements, the struct x is at the same address in memory as its first element, x.a. So when you printf them, you print the very same piece of memory.
Note that printing the struct type (printf(" x = %d\n",x)) via %d is technically undefined behaviour (by definition of printf). You get the same results here because enr is a POD and the compiler can somehow work around with that.
Another side note: In C++ a struct is a named type. So it is enough to just write struct enr {...}; The typedef you used is an old C-style.
C has no knowledge of structure member types at runtime. But you told it what the type was with the "%d" in your printf. It printed the value of the integer at x.a not because a was declared to be an integer, but because you told it to. Likewise, x without the member refers to the structure as a whole, but since its address is the same as the address of its first member, and you told it to look for an int there, it found one. If your printfs had used "%f", it would have printed a floating point number represented by the bits at that address for both expressions.
I am using gcc version 4.3.3 on my Ubuntu (i686). I have written a stripped down test program to describe my lack of understanding and my problem. The program shall tell me the size of the struct, which I implemented. So I have a typedef struct for a Message and a little main to play around:
#include <stdio.h>
typedef struct {
int size;
enum {token=0x123456};
} Message;
int main(int argc, char * argv[])
{
Message m;
m.size = 30;
printf("sizeof(int): %d\n",sizeof(int));
printf("sizeof(0x123456): %d\n",sizeof(0x123456));
printf("sizeof(Message): %d\n",sizeof(Message));
printf("sizeof(m): %d\n",sizeof(m));
}
While compiling this source with gcc I get the following warning, which I don't understand:
$ gcc sizeof.c
sizeof.c:5: warning: declaration does not declare anything
Line 5 refers to the enum line. I want that token in every Message, that I create. What am I doing wrong? What do I have to change to get rid of that warning?
My main contains several calls of sizeof(). When I run the program, you can see in the output that the integer has the size of four, the hex number has the size of 4, but the typedef struct Message has the size of 4, too:
$ ./a.out
sizeof(int): 4
sizeof(0x123456): 4
sizeof(Message): 4
sizeof(m): 4
That is very confusing to me. Why has Message the size of 4, although it contains an integer and an integer within an enum, each with the size of 4. If the sizeof(Message) would be at least 8, it would be logical to me.
But why is it only 4? How do I get the real size in Bytes of my Message? Or is this really the real size? If so, why?
Is there a difference in getting the size of a Message between C and C++?
An enumeration doesn't actually need any space, it's just a way for the compiler to recognize a set of literal numbers by a name.
You are not declaring anything with:
enum {token=0x123456};
Your declaration is similar to:
typedef struct {
int size;
int;
} Message;
If you declare your struct like this:
typedef struct {
int size;
enum {token=0x123456} e;
} Message;
There will be two fields, but e will not be initialized to anything. You need to set it manually for every instance: message.e=token.
The correct way to achieve what you want is, to use constructors in C++:
struct Message {
int size;
int token;
Message() : token(0x123456) {};
};
Or non-static data member initializers in C++11:
struct Message {
int size;
int token=0x123456;
};
There is no way to initialize field in struct declaration in C.
Line 5 does not declare any variable that is of type enum. So the compiler does the only thing it can do: ignore it.
If you want to create a member of that type in the struct, write something like
enum {token=0x123456} thetoken;
But be aware that this field can only have one valid value, is that what you want?
Edit:
Oh, and to answer your other question: I can't see a difference in output when compiling as C or C++. But there is a difference between how how you should write struct definitions.
typedef struct {
int size;
enum YouShouldDeclareAName {token=0x123456};
} Message;
your enum is a subclass/subtype of your Message struct, therefore bounds to Class and not object. Like a namespace. You do not create any variable with it.
Change it to:
typedef struct {
int size;
enum YouShouldDeclareAName {token=0x123456} token;
//or
YouShouldDeclareAName token2;
} Message;
You've defined a constant Message::token that's shared between all objects. Since it's shared, it doesn't count towards the size of a single object.
As the others answers note, you've declared an enumerated type, you just happened to do it inside a structure instead of at global scope. There's nothing to store, so it uses no memory.
Now if you were to declare an instance of your enumeration in that structure...
typedef struct {
int size;
enum {token=0x123456} e;
} Message;
int main(int argc, char * argv[])
{
Message m;
m.size = 30;
printf("sizeof(m): %d\n",sizeof(m));
}
sizeof(m): 8
Press any key to continue . . .
LINE 5:
enum {token=0x123456};
This line doesn't define any enum variable, its a declaration, because of this your compiler complains about line 5 saying its only a declaration.
proper usage should be:
enum {xyz=5} enum_variable_name;
Only then the compiler will allocate space for this.
Just like class, function, enum, static menber doesn't store in the object space!
The given C code
#include <stdio.h>
int x = 14;
size_t check()
{
struct x {};
return sizeof(x); // which x
}
int main()
{
printf("%zu",check());
return 0;
}
gives 4 as output in C on my 32 bit implementation whereas in C++ the code
#include <iostream>
int x = 14;
size_t check()
{
struct x {};
return sizeof(x); // which x
}
int main()
{
std::cout<< check();
return 0;
}
outputs 1. Why such difference?
In C++ class declaration struct x {}; introduces the name x into the scope of check and hides x (previously declared as int at file scope). You get 1 as the output because size of empty class cannot be zero in C++.
In C, an inner scope declaration of a struct tag name never hides the name of an object or function in an outer scope.You need to use the tag name struct to refer to the typename x (struct). However you can't have an empty struct in C as it violates the syntactical constraints on struct(however gcc supports it as an extension).
The C code is giving you the size of the global variable 'x', whereas the C++ code is giving the size of the empty struct.
To get the size of the struct x in the C code, use sizeof(struct x)
In C, struct tags live in a separate name space, and you have to use the struct keyword to access names in there. This is the reason that the "typedef struct {} x" idiom is so popular in C--it allows you to essentially promote struct names to the global namespace.
In C++, by contrast, structs (and all other names) live in the namespace surrounding the declaration, rather than a separate struct tag namespace as in C.
As Saurabh said, use sizeof(struct x) in C, or use the typedef struct {} x trick to get sizeof(x) to work as in C++.
As an added bonus, the C++ program outputs 1 because concrete class objects must have nonzero size (so that different objects must have different addresses), so the compiler has padded the struct with an anonymous char value.