Strange error with simple struct [duplicate] - c++

First:
int k[] ={1,2,3,4,5};
Second:
struct slk
{
int k[] ={1,2,3,4,5};
};
for those two statements, why does the first one pass the compilation but the second one give me
error:too many initializers for 'int [0]'. the compilation would passed if I set k[5];
What does this error message means? Note: code tested on GNU GCC version 4.7.2

In C++11, in-class member initializers are allowed, but basically act the same as initializing in a member initialization list. Therefore, the size of the array must be explicitly stated.
Stroustrup has a short explanation on his website here.
The error message means that you are providing too many items for an array of length 0, which is what int [] evaluates to in that context.

In the first example, something (actual memory allocation) is actually happening. The computer easily counts the number of items given to it and uses this as the capacity. In the second use, as part of a struct, the array is simply part of the template of a struct. In the second case, a size must explicitly be given and known at compile-time. There is no automatic counting here. It's in a similar vein to function declarations versus definitions as well as variable declarations (tells type but memory is untouched) and their invocation/use (where the program acts).

Probably cause in a struct the compiler needs you to specify the size explicitly.
C initialize array within structure (pun intended)

These are two completely different contexts:
The first is a variable declaration (with an initialiser clause).
The second is a type definition.

Related

Is it possible to have a recursive typedef?

The following doesn't work. Is there some way to get around this?
using Node = std::variant<Foo, Bar, std::vector<Node>>;
The error produced is "error: 'Node' was not declared in this scope"
There is a simple reason why such a data structure often cannot exist. You cannot tell the size of it. For all objects the size must be clear already at compile time. But in your case this is not the show stopper. The variant or vector bring their own memory management that makes such things possible.
But the way how the C++ compiler technically ensures that all sizes are known at compile time is to enforce that all types are properly defined before they are used. Therefore recursive definition like you have in your type are not legal in C++.
But there is an exception (in order to allow explicitly things like your type). For structs it possible to have recursive type definition. The reason is that in OOP programming you often need such things (see the discussion here: Linked lists in C++)
The solution then looks like this:
struct Node{
std::variant<Foo, Bar, std::vector<Node>> value;
};
It looks also incorrect. But indeed C++ accepts it. Node is an incomplete type. For structs this is accepted.

How to get the size of an array of objects? - No instance of overloaded function "std::size"

I'm running into a problem with C++ that should have an easy solution, but nothing I've tried yet seems to work.
How do I go about getting the size/number of elements of an array if both std::size() and std::sizeof() are throwing errors?
For context, FString is Unreal Engine's version of std::string. Each one is a class instance. I've got a guessing game class with a static array of FStrings to query from. It looks a bit like;
FString UBullCow::Words[] = {"hello", "goodbye", etc...};
class UBullCow
{
static FString Words[];
// etc.
}
So, as I understand it, I'm dealing with an array of pointers somewhere in the heap. So, in other words, an array of integers, right?
Well, in one of the class' private functions, I need the size of the Words array. Here's what I've tried;
std::size(Words);
Err(304): no instance of overloaded function "std::size" matches the argument list -- argument types are: (FString [])
std::sizeof(Words)/std::sizeof(Words[0]);
Err(40): expected an identifier
Why wouldn't std::size(Words) work here? Is there a workaround, or a fix? What am I doing wrong?
static FSring Words[];
When your C++ compiler processes this declaration this is the only thing this declaration specifies: Words is an array of some unspecified size. By definition it's size is not known.
Defining this array, in one translation unit, does not change this. Its size may be defined, in that translation unit. But its size is still unknown in any other translation unit, subsequent to this declaration.

variable declaration (implicit and explicit and advantages & disadvantages)

"What are explicit declaration & implicit declaration of variables in programming language concepts and their advantages and disadvantages?"
An explicit declaration is when you start making the variable by order it first.
ex: String name; name="yourname";
the advantages is you be able to fill your variable with any algorithm or math logic to make a value. the disadvantages is when you use it as a material without fill the value of your variable ,there will be an error.
An implicit declaration is when you make a variable directly without order it first. ex : String name="yourname";
the advantages : it is a practically treatment at some condition.
.
Explicit means declaring variable like in c.
Implicit declaration in variable declaration in python.
In Explicit we should cast.
In implicit no need of casting.
Explicit variable declaration means that the type of the variable is declared before or when the variable is set. Implicit variable declaration means the type of the variable is assumed by the operators, but any data can be put in it.
In C,
int x = 5; printf(x-5); x = "test"; printf(x-5);
returns a compile time error when you set x to test
but in Python,
x = 5; print(x-5); x = "test"; print(x-5);
will "compile" (python doesn't compile, but it will run the program) and give you a runt time error when you try to subtract from the string.
One advantage of Implicit variables is that it makes it easier to write code without worrying about the behind the scenes data type, the compiler should pick the appropriate one based on its future usage.
Another advantage is that you can flexibly type a variable to hold different things that may not even share a parent class. Doing this is risky, as you have no guarantees that the objects will be interpreted correctly by following code.
One disadvantage is that Implicit variables have no guarantees of what they are. A function that computes the difference between two numbers will not return an compile time error if the variables have strings in them. You passed in two variables, it is up to you to ensure they are the right type. It also makes reading code harder in some ways. var nextLocation = LeftHandedSmokeShifter(3.3) is completely legitimate code, but You have to look up the function to even guess what it is doing. string nextLocation = LeftHandedSmokeShifter(3.3) at least tells me that I should be using the output for mathematical operations.
Type heavy languages are always explicitly declared and typed, but type weak languages are mostly implicitly typed. If you can set a variable to "Var" it is likely an implicitly typed language.

"Only static constant integral variables may be initialized within a class "

can someone explain to me why cant i initialize a static variable inside the class ? what happens in compilation time exactly ?
for example :
class Object {
static int numberOfObjects = 0; // This gives the error
Object(){
nummberOfObjects++;
}
};
Thanks !
It's just a rule from the standard that was implemented by the compiler. The fact that it was a rule doesn't mean the opposite isn't possible, as the change in the newer C++11 standard and according compilers show.
In versions of C++ prior to C++11, the language standard simply doesn't allow you to perform a static variable definition inside the class declaration. In other words, You can't initialize it because it isn't constant. Since it can change during execution, the compiler needs some memory allocated somewhere to actually keep the value in. Since this is a class declaration, it doesn't actually allocate the memory for you. This issue doesn't exist for const values because they don't need memory assigned -- they are effectively "hard coded" just like if you replaced them with literals (or an old 'C' style #define).
You need a line of code outside of the class declaration that basically says:
int Object::numberOfObjects = 0;
This line isn't just initializing the static class variable, it's actually allocating a static int that will be used to store the value. The line of code up in the class declaration doesn't do this -- it merely tells the compiler that such a value exists somewhere.
Note that starting with C++11 this behavior is different. The language is now smart enough to figure out that you DO want to that memory defined, so you no longer need to do so manually.

Do the C++ standards guarantee that unused private fields will influence sizeof?

Consider the following struct:
class Foo {
int a;
};
Testing in g++, I get that sizeof(Foo) == 4 but is that guaranteed by the standard? Would a compiler be allowed to notice that a is an unused private field and remove it from the in-memory representation of the class (leading to a smaller sizeof)?
I don't expect any compilers to actually do that kind of optimization but this question popped up in a language lawyering discussion so now I'm curious.
The C++ standard doesn't define a lot about memory layouts. The fundamental rule for this case is item 4 under section 9 Classes:
4 Complete objects and member subobjects of class type shall have nonzero size. [ Note: Class objects can be assigned, passed as arguments to functions, and returned by functions (except objects of classes for which copying or moving has been restricted; see 12.8). Other plausible operators, such as equality comparison, can be defined by the user; see 13.5. — end note ]
Now there is one more restriction, though: Standard-layout classes. (no static elements, no virtuals, same visibility for all members) Section 9.2 Class members requires layout compatibility between different classes for standard-layout classes. This prevents elimination of members from such classes.
For non-trivial non-standard-layout classes I see no further restriction in the standard. The exact behavior of sizeof(), reinterpret_cast(), ... are implementation defined (i.e. 5.2.10 "The mapping function is implementation-defined.").
The answer is yes and no. A compiler could not exhibit exactly that behaviour within the standard, but it could do so partly.
There is no reason at all why a compiler could not optimise away the storage for the struct if that storage is never referenced. If the compiler gets its analysis right, then no program that you could write would ever be able to tell whether the storage exists or not.
However, the compiler cannot report a smaller sizeof() thereby. The standard is pretty clear that objects have to be big enough to hold the bits and bytes they contain (see for example 3.9/4 in N3797), and to report a sizeof smaller than that required to hold an int would be wrong.
At N3797 5.3.2:
The sizeof operator yields the number of bytes in the object
representation of its operand
I do not se that 'representation' can change according to whether the struct or member is referenced.
As another way of looking at it:
struct A {
int i;
};
struct B {
int i;
};
A a;
a.i = 0;
assert(sizeof(A)==sizeof(B));
I do not see that this assert can be allowed to fail in a standards-conforming implementation.
If you look at templates, you'll notice that "optimization" of such often ends up with nearly nothing in the output even though the template files may be thousands of lines...
I think that the optimization you are talking about will nearly always occur in a function when the object is used on the stack and the object doesn't get copied or passed down to another function and the private field is never accessed (not even initialized... which could be viewed as a bug!)