Initialising variables in C++ with {} - c++

I am using C++ in Visual Studio Code. When I want to initialise a variable I cannot initialise it with {} (e.g., int x {0};). Instead, I have to use () (e.g., int x (0);).
The error I get when using {} is "error: expected ';' at end of declaration" Although I have put ; at the end of declaration.
I'm using clang 11.0.0 as the compiler. Is it related to the compiler?
The code runs through the terminal by ./filename command. However, it gives errors when running by coderunner extension in VSCode.

In order to initialize a variable with {} you must say it is = {}.
Like this:
int x = {3}; //you wouldn't really do this for simple variable though I don't think since you can just say int x = 3;
//or if you are making a custom object you might say:
MyObject object = {"apples", 3, "red"};
// to set the variables inside the object. in the order they are declared.
I hope this answers your question!

Related

Statically initialize nested C++ structures with named labels using g++

I am importing/porting existing C code to C++. I am hoping to make as few changes to the existing body of code as possible to minimize preterbing the existing code.
This code makes use of static named initialization of nested structures. For quick made up example:
Car car =
{
.color = RED,
.tire.tread = OLD,
.tire.diameter = 27.106,
.tire.material.type = RUBBER,
.tire.material.density = 700,
};
I figured out that these are called designated initializers.
I learned about GNU initializers but I haven't figured out how to implement hierarchy with it.
I read that designated initializers are supported in g++ with c++11 enabled, but that didn't seem to work for me.
The code I am porting has pages of initialization with at least four layers deep of hierarchy. So I am trying to look for a straightforward transformation which doesn't get too involved.
I am looking for one of these possible solutions:
How to enable C99 designated initializers
How to formulate hierarchical GNU style initialization
What is a C++ equivalent way to do this which wouldn't be error prone transcribing war and peace.
An obvious solution I haven't thought of
I am using g++ version
g++.exe (i686-posix-dwarf-rev0, Built by MinGW-W64 project) 8.1.0
The use of such nested designated initializers seems to be something of an edge case. The following works in both clang-cl (in Visual Studio 2019) and the native MSVC compiler (but the latter only with the /std:c++latest option, which uses the draft C++20 standard):
struct inner {
int x, y;
double z;
};
struct outer {
char a;
double b;
inner c;
};
outer my_outer = { .a = 'a', .b = 1.2, .c = { .x = 3, .y = 4, .z = 5.6 } };
With clang-cl, the initializer can be abbreviated to the following form:
outer my_outer = { .a = 'a', .b = 1.2, .c.x = 3, .c.y = 4, .c.z = 5.6 };
but MSVC complains in this case, with:
error C7558: nested member access is not allowed in standard C++
designated initializers; use a nested initializer list
So, for your example, you could try this:
Car car =
{
.color = RED,
.tire = {
.tread = OLD,
.diameter = 27.106,
.material.type = RUBBER,
.material.density = 700,
}
};
There's a helpful 'discussion' of the topic on cppreference, with this part being notable:
...each designator must name a direct non-static data member of T, and
all designators used in the expression must appear in the same order
as the data members of T.

Why doesn't C++ allow const after ::?

Folks,
Problem Statement - Does C++ allow a (static) const be limited to a class scope, so I can get rid of #defines that pollute entire namespace?
My observation is NO (in the following DIFFERENT examples), and I'd like to find out why and what's the best alternative. VS generates error C2589: 'const' : illegal token on right side of '::'
EXAMPLE1
// a.h
class A
{
…
..
static const uint_32 myConst = 1234;
};
//b.cpp
include “a.h”
…
B()
{
uint32_t arr[A::myConst]; // C2589! const : illegal token on right side of '::'
}
EXAMPLE 2
// a.h
class A
{
…
..
enum blah
{
...
myConst = 1234,
..
};
};
//b.cpp
include “a.h”
...
B()
{
uint32_t arr[A::myConst]; // C2589! const : illegal token on right side of '::'
}
When you take your macro:
#define CONST 1234
and substitute it for where you use it:
static const int CONST = 1234;
The end result is nonsense:
static const int 1234 = 1234;
In another instance:
Int a1[a::CONST];
This also becomes nonsense:
Int a1[a::1234];
This all begs the question, what are you trying to do?
It looks like you're trying to create a member variable with the same name as your macro, CONST, here:
class A
{
static const int CONST = 1234;
};
However since when this code is compiled the macro has already been defined, the preprocessor changes this by substituting the macro before the compiler itself can get a crack at it. By the time the code is compiled, it looks like this:
class A
{
static const int 1234 = 1234;
};
Best is to just do away with the macro entirely, and then retrofit your code to use proper constants like you're trying to do here. Don't mix and match. At the very least, don't use the same name for the member as you do for the macro.
First of all your class is called A, as in capital A, not a. The class name is used to qualify the constant you are trying to use. So, change your code to use A::CONST. By the way, this is C++ not C# or Java, so there is no such thing as an Int, unless for some bizarre reason you decided to invent your own integer type.
As an aside, using all caps to name constants can collide with macros and is a good way to get into trouble, especially since pre-processing happens first and macros are substituted for all cases of the constants. This can often lead to invalid C++ code with syntax errors that are difficult to understand. That's why you should never use all caps to name constants, since this is a convention most commonly used for macros.
If I may make a guess, it looks like you're trying to use :: the same way you use . in Python.
It looks like you really don't understand what the scope resolution operator does, or how it works.
:: has a very specific, and quite limited usage. Until you understand it better, we're going to have a really hard time helping you.

C: compiling C++ code in C

I'm trying to export some C++ code in a C project...
Actually I'm stuck with the following problem:
_CreateToolhelp32Snapshot fnCreateToolhelp32Snapshot = (_CreateToolhelp32Snapshot) GetProcAddress(GetModuleHandleA(L"kernel32"), "CreateToolhelp32Snapshot");
_Thread32First fnThread32First = (_Thread32First) GetProcAddress(GetModuleHandleW(L"kernel32"), "Thread32First");
_Thread32Next fnThread32Next = (_Thread32Next) GetProcAddress(GetModuleHandleW(L"kernel32"), "Thread32Next");
I'm saving the memory address of the three functions ("CreateToolhelp32Snapshot", "Thread32First" and "Thread32First") in three objects in C programming... I'm compiling with mingw under Ubuntu 13.04 and I get this error:
(row 1): error: initializer element is not constant
(row 2): error: initializer element is not constant
(row 3): error: initializer element is not constant
I know that in C the address function are not considered as constant values, but will be very helpful find the way to resolve this constraint...
Thanks in advance for any suggestion...
You must be using global variables. Use an initialize function to set those values, before using it elsewhere. In standard c, you cannot execute code (like calling GetProcAddress function) before entering main.
_CreateToolhelp32Snapshot fnCreateToolhelp32Snapshot;
_Thread32First fnThread32First;
_Thread32Next fnThread32Next;
void initialize()
{
fnCreateToolhelp32Snapshot = (_CreateToolhelp32Snapshot) GetProcAddress(GetModuleHandleA(L"kernel32"), "CreateToolhelp32Snapshot");
fnThread32First = (_Thread32First) GetProcAddress(GetModuleHandleW(L"kernel32"), "Thread32First");
fnThread32Next = (_Thread32Next) GetProcAddress(GetModuleHandleW(L"kernel32"), "Thread32Next");
}
int main()
{
initialize();
...
}

How to use C++ enums without getting a compiler warning

I need to communicate that one and the same enum is passed to several calls. So I am doing this:
MiddleEarth::Creatures ally = MiddleEarth::Creatures::Elf;
myEnergy->Transfer(ally, 10);
myLives->Transfer(ally, 1);
Both Transfer methods are declared as follows:
Energy::Transfer(const Creatures& transferTo, (snip)
However, I am getting the following warning on the declaration of the variable named ally:
warning C4482: nonstandard extension used: enum 'MiddleEarth::Creatures' used in qualified name
What am I doing wrong? How do I rewrite my code so that it does not generate a compiler warning?
From the MSDN page on the warning;
When you refer to an enum inside a type, you do not need to specify the name of the enum.
int i = S::E::a; // C4482
int j = S::a; // OK
so in your case;
MiddleEarth::Creatures::Elf
should be
MiddleEarth::Elf
You probably want:
MiddleEarth::Creatures ally = MiddleEarth::Elf;

Does Bada IDE have code completion and meaningful error messages?

I'm trying to upgrade a Bada app from 1.2 to 2.0 with no experience of Bada. I have the project building and can run it in the emulator but I get a load of warnings and I cant click the text boxes to get a keyboard and enter anything in the emulator.
Unfortunately the warning messages are completely cryptic to me, for example
SearchForm::SearchForm(void) :
gives the warning message "when initialized here"
What when initialized here??!!
Also, all the TryCatch statements show syntax error, and nothing I have found on the internet seems to make it happy:
result OnDraw()
{
result r = E_SUCCESS;
Canvas* readerCanvas = GetCanvasN();
TryCatch(E_SUCCESS == GetLastResult(), "Failed to get canvas: %S", GetErrorMessage(r));
if (readerCanvas)
{
Rectangle tempRect(0, 0, GetBounds().width, GetBounds().height);
Point tempPoint(0, 0);
r = readerCanvas->Copy(tempPoint, *iDrawingCanvas, tempRect);
TryCatch(E_SUCCESS == r, "Failed to copy canvas: %S", GetErrorMessage(r));
delete readerCanvas;
}
return r;
CATCH:
delete readerCanvas;
return r;
}
The TryCatch line says "statement has no effect", if I try edit it to match the examples I'v found I get a syntax error.
What's up with this?
It seems like you are trying to outdo your IDE's supposed bad messages by quoting them entirely out of context and only partially. Let me break it down:
TryCatch
The macro is defined as
TryCatch(condition, cleanup, message)
When the condition is evaluated to false, this will goto CATCH. You could think of the macro like this:
if (!condition)
{
goto CATCH;
}
For example, you can use it like this:
void TryCatchDemo::UseTryCatch(void)
{
TryCatch(1==2, , "1 is NOT 2");
AppLog("This should not appear");
CATCH:
AppLog("Catch block");
}
Now, your second parameter is a string literal, "Failed to get canvas: %S", which unsurprisingly, doesn't have an effect when used as statement:
"does nothing";
123; // just like this
So the compiler is being nice to warn you of the fact that you probably had something else in mind. Note also, that statement has no effect is not a syntax error.
"when initialized here"
Know your language! The code quoted isn't legal C++ to begin with:
SearchForm::SearchForm(void) :
At best this is the beginning of a constructor definition, with a missing initializer list and body. In the C++ language spec, class members are initialized in the order in which they were declared, not in the order in which they appear in the initializer list. A minimal example:
struct X
{
int a, b;
X() : b(), a() {}
};
This results in the compiler warning:
/tmp/test.cpp|3 col 13| warning: ‘X::b’ will be initialized after [-Wreorder]
/tmp/test.cpp|3 col 10| warning: ‘int X::a’ [-Wreorder]
/tmp/test.cpp|4 col 6| warning: when initialized here [-Wreorder]
As you can see, you not only clipped the code but also the warnings! If you read the whole message and the whole code, the fix would be pretty obvious:
struct X
{
int a, b;
X() : a(), b() {}
};
Bonus: In case you were wondering, why the ordering matters, consider what happens when you do:
struct X
{
int a, b;
X() : b(), a(b) {} // OOPS!
};
Hope this helps
Using a Format String with the Macros
Edit I just noted this: it is probably not supported to use format strings inside the Try/Catch macros:
Each of the macros that support a message parameters actually support format strings. A format string is similar to the format string of printf on systems that support it (bada does NOT support it)