Incompatibility between C and C++ code - c++

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.

Related

Musing about variable declaration and the typedef specifier in c++

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 ?

Strange code... Can someone explain me this

Hi I am switching to C++ from C. While reading http://www.gotw.ca/publications/xc++.htm I see this code block.
const int i = 1;
const int j = 2;
struct x
{
int x;
};
namespace y
{
int i[i];
int j = j;
x x;
int y::y = x.x;
};
And I am totally confused about this specially in namespace y section.
Please explain me the behavior of this code and use of namespace. Also I read somewhere that bad use of namespace leading to violating fundamentals of inheritance. Please give me some examples of using namespace brilliantly.
This example is using some horribly obfuscated code to illustrate a point about the scope of names. From C++11 §3.3.6 [basic.scope.namespace] p1:
... A namespace member name has namespace scope. Its potential scope includes its namespace from the name’s point of declaration (3.3.2) onwards ...
point of declaration is defined in §3.3.2 [basic.scope.pdecl] p1:
The point of declaration for a name is immediately after its complete declarator (Clause 8) and before its initializer (if any), except as noted below.
So it is possible to use e.g. the name i from an outer scope in the initializer of something named i in an inner scope. The code in question:
const int i = 1;
const int j = 2;
struct x
{
int x;
};
namespace y
{
int i[i];
int j = j;
x x;
int y::y = x.x;
}
declares:
y::i as an array of 1 int that will be implicitly zeroed (since all static storage duration objects are zero-initialized if they have no explicit initializer),
y::j as an int with initial value 2,
y::x as struct of type ::x that will be implicitly zeroed, and
y::y is an invalid name. If it was simply y, it would be an int with initial value 0, since its initializer y::x.x is implicitly zero-initialized.
Here's a demo (with y::y changed to y) at Coliru.
NOTE: DO NOT EVER WRITE CODE LIKE THIS. The only time using this feature of names even borders on being acceptable is for member initializers in a class constructor. If you do this anywhere else, I will find you. And I will make you pay.
I think there is some problem with your code. The int y::y = x.x; section is wrong as there is no y previous to this and so this statement needs some correction. I am trying to give some basic info about namespace and its usage, hope it helps.
The main purpose of namespaces is to logically group functionality without the need of long names and the option for handy usage via "using". You can also use same name over different namespaces
namespace Color
{
class Add {};
class Multiply {};
};
namespace Dimension
{
class Add {};
class Multiply {};
};
So you can use the same class name Add, Multiply under two namespaces and one thing which you have to remember is that use namespaces only when required otherwise you will spam the global namespace "std" unknowingly which is not conventional.
For using namespace with inheritance you can search for articles in stack over flow and definitely you will get some. Ex: Accessing Parent Namespace in C++
int i[i]; //line 1
It creates an int array of size 1, as the index i is a constant initialized to 1
int j = j; //line 2
It declares and initilizes a variable j to 2(value of constant j) in a namespace y
x x; //line 3
It creates a structure variable x of type struct x ( Note: The structure variable x is different from the int x present inside the structure x, int x is a member of structure x
int y::y = x.x; //line 4
This is syntactically wrong, there is no need to qualify int y with namespace('y'), as it is already present in the namespaace y, So the statement should be
int y = x.x
where x.x represents accessing the data member (int x) of structure variable x created in the line 3
Namespace example Have a look on this example,it helps you to understand namespaces clearly. Refer the link for more examples [link]http://www.cplusplus.com/doc/tutorial/namespaces/
#include <iostream>
using namespace std;
namespace first
{
int x = 5;
int y = 10;
}
namespace second
{
double x = 3.1416;
double y = 2.7183;
}
int main () {
using namespace first;
cout << x << endl;
cout << y << endl;
cout << second::x << endl;
cout << second::y << endl;
return 0;
}
//Output
5
10
3.1416
2.7183
......Hope it helps you....:)

C/C++: size of a typedef struct containing an int and enum == sizeof(int)?

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!

What is a common C/C++ macro to determine the size of a structure member?

In C/C++, how do I determine the size of the member variable to a structure without needing to define a dummy variable of that structure type? Here's an example of how to do it wrong, but shows the intent:
typedef struct myStruct {
int x[10];
int y;
} myStruct_t;
const size_t sizeof_MyStruct_x = sizeof(myStruct_t.x); // error
For reference, this should be how to find the size of 'x' if you first define a dummy variable:
myStruct_t dummyStructVar;
const size_t sizeof_MyStruct_x = sizeof(dummyStructVar.x);
However, I'm hoping to avoid having to create a dummy variable just to get the size of 'x'. I think there's a clever way to recast 0 as a myStruct_t to help find the size of member variable 'x', but it's been long enough that I've forgotten the details, and can't seem to get a good Google search on this. Do you know?
Thanks!
In C++ (which is what the tags say), your "dummy variable" code can be replaced with:
sizeof myStruct_t().x;
No myStruct_t object will be created: the compiler only works out the static type of sizeof's operand, it doesn't execute the expression.
This works in C, and in C++ is better because it also works for classes without an accessible no-args constructor:
sizeof ((myStruct_t *)0)->x
I'm using following macro:
#include <iostream>
#define DIM_FIELD(struct_type, field) (sizeof( ((struct_type*)0)->field ))
int main()
{
struct ABC
{
int a;
char b;
double c;
};
std::cout << "ABC::a=" << DIM_FIELD(ABC, a)
<< " ABC::c=" << DIM_FIELD(ABC, c) << std::endl;
return 0;
}
Trick is treating 0 as pointer to your struct. This is resolved at compile time so it safe.
You can easily do
sizeof(myStruct().x)
As sizeof parameter is never executed, you'll not really create that object.
Any of these should work:
sizeof(myStruct_t().x;);
or
myStruct_t *tempPtr = NULL;
sizeof(tempPtr->x)
or
sizeof(((myStruct_t *)NULL)->x);
Because sizeof is evaluated at compile-time, not run-time, you won't have a problem dereferencing a NULL pointer.
In C++11, this can be done with sizeof(myStruct_t::x). C++11 also adds std::declval, which can be used for this (among other things):
#include <utility>
typedef struct myStruct {
int x[10];
int y;
} myStruct_t;
const std::size_t sizeof_MyStruct_x_normal = sizeof(myStruct_t::x);
const std::size_t sizeof_MyStruct_x_declval = sizeof(std::declval<myStruct_t>().x);
From my utility macros header:
#define FIELD_SIZE(type, field) (sizeof(((type *)0)->field))
invoked like so:
FIELD_SIZE(myStruct_t, x);

Template Metaprogramming - Difference Between Using Enum Hack and Static Const

I'm wondering what the difference is between using a static const and an enum hack when using template metaprogramming techniques.
EX: (Fibonacci via TMP)
template< int n > struct TMPFib {
static const int val =
TMPFib< n-1 >::val + TMPFib< n-2 >::val;
};
template<> struct TMPFib< 1 > {
static const int val = 1;
};
template<> struct TMPFib< 0 > {
static const int val = 0;
};
vs.
template< int n > struct TMPFib {
enum {
val = TMPFib< n-1 >::val + TMPFib< n-2 >::val
};
};
template<> struct TMPFib< 1 > {
enum { val = 1 };
};
template<> struct TMPFib< 0 > {
enum { val = 0 };
};
Why use one over the other? I've read that the enum hack was used before static const was supported inside classes, but why use it now?
Enums aren't lvals, static member values are and if passed by reference the template will be instanciated:
void f(const int&);
f(TMPFib<1>::value);
If you want to do pure compile time calculations etc. this is an undesired side-effect.
The main historic difference is that enums also work for compilers where in-class-initialization of member values is not supported, this should be fixed in most compilers now.
There may also be differences in compilation speed between enum and static consts.
There are some details in the boost coding guidelines and an older thread in the boost archives regarding the subject.
For some the former one may seem less of a hack, and more natural. Also it has memory allocated for itself if you use the class, so you can for example take the address of val.
The latter is better supported by some older compilers.
On the flip side to #Georg's answer, when a structure that contains a static const variable is defined in a specialized template, it needs to be declared in source so the linker can find it and actually give it an address to be referenced by. This may unnecessarily(depending on desired effects) cause inelegant code, especially if you're trying to create a header only library. You could solve it by converting the values to functions that return the value, which could open up the templates to run-time info as well.
"enum hack" is a more constrained and close-enough to #define and that helps to initialise the enum once and it's not legal to take the address of an enum anywhere in the program and it's typically not legal to take the address of a #define, either. If you don't want to let people get a pointer or reference to one of your integral constants, an enum is a good way to enforce that constraint. To see how to implies to TMP is that during recursion, each instance will have its own copy of the enum { val = 1 } during recursion and each of those val will have proper place in it's loop. As #Kornel Kisielewicz mentioned "enum hack" also supported by older compilers those forbid the in-class specification of initial values to those static const.