There is an union in C and embedded into C++ as below:
typedef union MyUnion MyUnion_;
union MyUnion{
ULONG mLong;
char mChar;
...
};
When I trying to init it like:
MyUnion_ test;
test = (MyUnion_)NULL;
this is can compile by Mingw32, but gives
error: C2440: 'type cast': cannot convert from 'void *' to 'MyUnion_'
in VC++ (VS2015). So how to do cast & initialize of union in VC++ compiler?
Now I am doing like this:
MyUnion_ test;
test.mLong = NULL;
but this makes the program look bad when passing union as a parameter.
void test(MyUnion_ u)
ULONG i = 0;
// mingw32
test((MyUnion_)i);
// vc++
MyUnion_ temp;
temp.mLong = i;
test(temp);
Using a compiler that supports the C++11 uniform initialization syntax you can use a braced initializer with a single value which will be used to initialize the first non-static field of the union …
MyUnion test{ 0 };
You could use NULL instead of zero in the code above but it seems confusing to initialise mLong (which is a ULONG) with NULL.
You can also use braced initialization in an assignment statement if you have to set the variable after it was declared …
MyUnion test{ 0 };
// ...
test = { 3 };
Note that the braced initializer syntax may also be available in older compilers that offer experimental support for what used to be called C++0x
Visual Studio 2015 C++ supports braced initializers unless you are compiling a file with a .c extension or are using the /TC switch to compile as C code (rather than C++ code).
Older C++ (and C) compilers
When using compilers that don't support braced initialization the older assignment initialization syntax can be used in declarations ...
MyUnion_ test = { 0 };
… but not in assignment statements.
Casting to union type
According to this IBM Knowledge Center article casting to a union type is an extension to C99 "... implemented to facilitate porting programs developed with GNU C" - which suggests it's not standard C.
This Microsoft documentation indicates there are no legal casts in C for a union, struct or array.
In C++ a cast to a union type is possible if a suitable constructor exists...
union MyUnion {
unsigned long mLong;
char mChar;
MyUnion(unsigned long val) { mLong = val; };
};
// valid cast
test = (MyUnion)3ul;
// invalid cast - no suitable constructor exists
void * ptr = 0;
test = (MyUnion)ptr;
Default constructor?
typedef union MyUnion MyUnion_;
union MyUnion {
ULONG mLong;
char mChar;
MyUnion(): mLong(0) {}
};
int main()
{
MyUnion_ temp;
return 0;
}
Related
I am fairly new to C++. I was practicing some ds,algo.This code looks fine to me, but I am getting some error about function not taking 2 arguments. Though I get some error asked in stackoverflow none of the cases match my problem.
#include <iostream>
#include <algorithm>
int ropecutting(int n, int *cuts){
if (n == 0)
return 0;
if (n < 0)
return -1;
int res = std::max(ropecutting(n-cuts[0], cuts), ropecutting(n-cuts[1], cuts), ropecutting(n-cuts[2], cuts));
if(res == -1) return -1;
return res+1;
}
int main(){
int n, cuts[3];
std::cin >> n;
for(int i = 0; i < 3; i ++)
std::cin >> cuts[i];
std::cout << ropecutting(n, cuts);
}
The error I get is,
main.cpp
G:\software_installation\Visual Studio Community 2017\VC\Tools\MSVC\14.16.27023\include\xlocale(319): warning C4530: C++ exception handler used, but unwind semantics are not enabled. Specify /EHsc
G:\software_installation\Visual Studio Community 2017\VC\Tools\MSVC\14.16.27023\include\algorithm(5368): error C2064: term does not evaluate to a function taking 2 arguments
G:\software_installation\Visual Studio Community 2017\VC\Tools\MSVC\14.16.27023\include\algorithm(5367): note: see reference to function template instantiation 'const _Ty &std::max<int,int>(const _Ty &,const _Ty &,_Pr) noexcept(<expr>)' being compiled
with
[
_Ty=int,
_Pr=int
]
G:\software_installation\Visual Studio Community 2017\VC\Tools\MSVC\14.16.27023\include\algorithm(5368): error C2056: illegal expression
Wishing someone would point me out in the right direction. Thank you.
Of the overloads of std::max, the only one which can be called with three arguments is
template < class T, class Compare >
constexpr const T& max( const T& a, const T& b, Compare comp );
So since it receives three int values, that function is attempting to use the third value as a functor to compare the other two, which of course doesn't work.
Probably the simplest way to get the maximum of three numbers is using the overload taking a std::initializer_list<T>. And a std::initializer_list can be automatically created from a braced list:
int res = std::max({ropecutting(n-cuts[0], cuts),
ropecutting(n-cuts[1], cuts),
ropecutting(n-cuts[2], cuts)});
I'm trying to restrict the use of some user defined litteral for string to a given length
Carte operator"" _C (const char* str, std::size_t sz) {
if (sz != 2)
throw runtime_error("Wrong size of string");
return from_string(str);
}
This works perfectly except that since litteral is known at compile time, the size test could be done at that time as well. However the I can't use a static assert here
jeu.cpp:105:17: error: static_assert expression is not an integral constant expression
static_assert(sz == 2, "Wrong size of string");
^~~~~~~
jeu.cpp:105:17: note: read of non-const variable 'sz' is not allowed in a constant expression
jeu.cpp:104:51: note: declared here
Is there a way to check the size of user defined string litteral at compile time in c++11 ?
If not, is it possible with more recent standard of c++ ?
use sizeof(test) to get length.. then you can use static_assert
const char test[] = "blablalba";
static_assert (sizeof(test) == 10);
in f1.h header using typedef for structure. sample code snippet shown below
typedef struct{
int a;
union u
{
int x;
char y;
}xyz;
}mystruct;
In f2.h header using the structure mysturct to get the offset. Code snippet shown below
static mystruct ktt
//#define OFFSET_T(b, c) ((int*)((&((mystruct*)0)->b)) - (int*)((&((mystruct*)0)->c)))
#define OFFSET_T(b, c) ((char*) &ktt.b - (char *) &ktt.c)
static struct Mystruct1{
int n;
}mystruct1 = {OFFSET_T(xyz,a)};
when i'm doing compilation in AIX machine using xlc compiler it is throwing the error as "1506-221(S) Initializer must be a valid constant expression".
i tried both the macro's but both are getting same error. Is there anything wrong in f2.h macro while performing size of structure to get offset ??
The expression in question needs to be an arithmetic constant expression in order to be portable. Neither macro qualifies, since operands of pointer type are involved and arithmetic constant expressions are restricted such that those operands are not allowed. In C11, this is found in subclause 6.6 paragraph 8.
That said, the code using the first macro (source reproduced below) does compile on multiple versions of the xlc compiler on AIX.
typedef struct{
int a;
union u
{
int x;
char y;
}xyz;
}mystruct;
static mystruct ktt;
#define OFFSET_T(b, c) ((int*)((&((mystruct*)0)->b)) - (int*)((&((mystruct*)0)->c)))
//#define OFFSET_T(b, c) ((char*) &ktt.b - (char *) &ktt.c)
static struct Mystruct1{
int n;
}mystruct1 = {OFFSET_T(xyz,a)};
The compiler invocation I used was:
xlc offsetcalc.c -c -o /dev/null
The version information for one of the older versions I tried is:
IBM XL C/C++ for AIX, V10.1
Version: 10.01.0000.0021
The version information for one of the newest versions I tried is:
IBM XL C/C++ for AIX, V13.1.3 (5725-C72, 5765-J07)
Version: 13.01.0003.0004
How do I implement below operation efficiently on msvc compiler?
uint32x4_t temp = { 1, 2, 3, 4 };
I have to load 4 different values in neon register very efficiently since I am working to optimize performance. Above statement works for android clang but fails on msvc compiler since uint32x4_t is typedef'ed to __n128.
Following is the structure of __n128:
typedef union __declspec(intrin_type) _ADVSIMD_ALIGN(8) __n128
{
unsigned __int64 n128_u64[2];
unsigned __int32 n128_u32[4];
unsigned __int16 n128_u16[8];
unsigned __int8 n128_u8[16];
__int64 n128_i64[2];
__int32 n128_i32[4];
__int16 n128_i16[8];
__int8 n128_i8[16];
float n128_f32[4];
struct
{
__n64 low64;
__n64 high64;
} DUMMYNEONSTRUCT;
} __n128;
In C99, when initializing a union with a initializer list, you can specify the particular members that are initialized, as follows:
uint32x4_t temp = { .n128_u32 = {1,2,3,4} };
However, this C99 syntax is only supported in Visual Studio 2013 and higher. Visual Studio 2012 and below do not support this feature, and thus, you can only initialize a union with a static initializer based on the first entry (n128_u64). You could come up with an initializer that fits your uint32 data into uint64. Since they are constants, it will not take any additional execution time. Looks really ugly:
uint32x4_t temp = { { 1 << 32 | 2, 3 << 32, 4 } };
If this code needs to be portable between compilers, a better option would be to create a preprocessor macro, that handles formatting of constants.
hi - I'm using the XC16 C compiler with a Microchip dsPIC33F CPU. I'm trying to use an enum to store the state of a device. I have accessors to get and set the device state. The state is (or should be) captured in a variable called "currentNodeState" which is declared with the following:
`
typedef enum NodeState currentNodeState;
I then use it in the set accessor with:
void SetNodeState(NodeState state)
{
currentNodeState = state;
}
which results in the following compiler error:Node_IO.c:168:22: error: expected identifier or '(' before '=' token
any suggestions as to why the error message
Jim
You need to define what values are legal for the enum.
Cplusplus has a good write up on enums (near the bottom of the page): http://www.cplusplus.com/doc/tutorial/other_data_types/
Here's a modified example from my code:
typedef enum
{
ADJUST_NONE,
ADJUST_FINE,
ADJUST_COARSE,
ADJUST_INVALID
} adjustment_state_t;
adjustment_state_t ADJUSTER_StateUpdate(adjustment_state_t currentState,
uint8_t thresholdViolation);
Valid inputs to the function are any of the values in the enum. ADJUST_NONE = 0, and each subsequent value is 1 higher than the last. That makes ADJUST_INVALID = 3.