Porting c++ code from unix to windows - c++

Hi i have to port some stuff written on c++ from unix bases os to windows visual studio 2008.
The following code implements array data type with void ** - pointer to the data.
struct array
{
int id;
void **array; // store the actual data of the array
// more members
}
When i compile with g++ on Unix it's ok but when i try with MSVS 2008 I get the error - error C2461: 'array' : constructor syntax missing formal parameters. When i change the member from 'array' to something else it works, so it seems that the compiler thinks that the member name 'array' is actually the constructor of the struct array. It's obviously not a good practice to name the member like the struct but it's already written that way. Can i tell the MSVS compiler to ignore this problem or i should rename all members that are the same as the struct name.

You are dealing with a bug in GCC compiler. C++ language explicitly prohibits having data members whose name is the same as the name of the class (see 9.2/13). MS compiler is right to complain about it. Moreover, any C++ compiler is required to issue a diagnostic message in this case. Since GCC is silent even in '-ansi -pedantic -Wall' mode, it is a clear bug in GCC.
Revison: What I said above is only correct within the "classic" C++98 specification of C++ language. In the most recent specification this requirement only applies to static data members of the class. Non-static data members can now share the name with the class. I don't know whether this change is already in the official version of the revised standard though.
That means that both compilers are correct in their own way. MS compiler sticks to the "classic" C++98 specification of the language, while GCC seems to implement a more recent one.

I'd say that if you're doing something that you yourself describe as "not a good practice", then you should change it.

I would rename your attribute to not have the same name as the class. This will make your code more portable. If you have to move to yet another compiler in the future, you won't run in to this problem again then.

Related

What does the ms-extensions flag do exactly with gcc?

GCC has a flag -fms-extensions.
What does this flag do exactly? Why is it sometimes on by default, and why does it exist?
According to the gcc 9.1.0 source code (grepped for flag_ms_extensions) the effects are:
(C) Allow Microsoft's version of anonymous unions and struct. This includes support for C11 anonymous unions and structs as well as Microsoft-specific flavours, including omitting the braced member list entirely, and placing members in the parent namespace even if the struct/union had an identifier.
(C++) Allow a class member to have the same name as its type (e.g. using foo = int; struct A { foo foo; }). With ms-extensions disabled, the behaviour is to accept this code in C (where it is legal); or an extern "C" block unless -pedantic flag was given. The error message for this is declaration of NAME changes meaning of NAME.
(C++) Allow implicit int; any situation that would have produced the diagnostic ISO C++ forbids declaration of NAME with no type is now allowed, with int assumed as the type. Examples: const *p; or const f();.
(C++) Allow implicit conversion from a qualified-id naming a non-static member function, to a pointer-to-member. In ISO C++ the & operator is required to perform that conversion.
(C++) Allow &f to form a pointer-to-member, if f (an unqualified-id) names a non-overloaded member function in that context. ISO C++ requires explicit qualification with the class name.
The flag is turned on by default if the Target ABI is a Microsoft ABI. It can be disabled by manually specifying -fno-ms-extensions.
The rationale behind this is a tougher question. The documentation has to say:
Accept some non-standard constructs used in Microsoft header files.
Disable Wpedantic warnings about constructs used in MFC.
So I assume the rationale is to allow g++ to build MFC applications which depend on non-standard code in MSVC vendor-supplied headers.
I am not sure how relevant that still is in 2019 and I think a good case could be made for gcc to default to having this flag turned off. (Users can always specify it if they want to build an old MFC app).
For example MSVC 19.xx (the latest version to date) no longer allows the last three bullet points in its default mode. (It does still allow foo foo; even with /Za flag).

Error:C2016 C requires that a struct or union has at least one member

I am a newbie in c/c++ and faced a problem using some c project headers in c++.
I have two solutions, where #one containing mostly c files (also few cpp) and the #two only cpp files. each solution gets compiled and runs correctly with no errors.
both are on VisualStudio v.15.9.4 VC++ 2017 targeting windows SDK 10.0.17134.0.
I did copy-paste some header files form #one to #two and on compile get the error in the title.
typedef struct
{
U32 RESERVED;
SHARED_TYPE * SHARED;
struct
{
} ALIEN; <--- HERE
} TxRequest;
Error C2016 C requires that a struct or union has at least one member
Error (active) E0169 expected a declaration
searching answers mostly where about the difference of compilers but
targeting the same SDK where not both solutions using the same compiler? why in one solution it get compiled with no error and in one with error?
how should I fix it having the same empty struct. as changing it might affect other parts.
Standard C does not permit empty structs, as the error message helpfully points out. Standard C++ does allow them, since they can be useful as template metavalues and for overload resolution, among other purposes.
From the error message, it seems that you are compiling that header with the Visual Studio C compiler.
Other compilers are more lenient. Empty C structs are a long-standing GCC extension, and were frequently used, as in this example, as another form of the so-called "struct hack". In its classic form, the struct hack consisted of putting an array of length 1 (or, using gcc, length 0) as a kind of placeholder for a variable length extension. In this case, the variable length extension is presumably a single object of unspecified type, as opposed to the classic struct hack where it is an array of objects of specified type but unspecified length.
So GCC (and Clang) accept that struct declaration as valid C unless you request strict validation with -pedantic (and even then, it shows up as a warning, not an error).
In general, a union would be a better solution here. But that requires knowing the various possible extensions to TxRequest, so it might be more trouble than it's worth.

std::string.npos validity

Was std::string.npos ever valid? (As opposed to the correct std::string::npos.)
I am seeing it a lot in an old project I'm working on, and it does not compile with VS2010.
Is it something from the pre-standard days?
The C with classes syntax for naming a class member was, in fact, a dot:
class X {
public:
void f();
};
void X.f() // a dot! see D&E 2.3
{
}
However, the :: syntax had not yet been invented. The std namespace didn't exist yet either. Thus the std::string.npos wasn't ever valid as either C with classes or standard C++.
I suspect std::string.npos is purely Microsoft's extension (or a bug?). It might be inspired by the old syntax, and might be not.
No, std::string.npos was never valid, and no, it's not something from the pre-standard days.
I see other answers mentioning that MSVC has allowed that notation.
However, MSVC is not a very compliant compiler. For example, it lets you freely bind a temporary to a reference to non-const. For another example, for Windows GUI subsystem applications you have to use not well-documented switches to make it accept a standard main. Much has improved since Microsoft hired Herb Sutter (and other guy that I don't remember the name of right now) to fix up their monstrous compiler. And in relative terms it has been really great, but in absolute terms, well that compiler is still a bit lacking.
Access to any static member via class name and dot was unfortunately allowed by prior versions of MSVC.
#include <iostream>
struct A
{
static int a;
};
int A::a;
int main()
{
std::cout << A.a;
}
This code is happily accepted by MSVC9.0 with a warning
Warning 1 warning C4832: token '.' is
illegal after UDT 'A'
The C++ standard obviously disallows access to a static member via className.memberName (although it is perfectly legal to access a static member via an object object.staticMemberName).
My common sense tells me that if MSVC is aware that this is not standard and gives a warning, then we can turn that extension off. We go to Project Propertied -> C/C++ -> Language and set Disable Language Extensions to Yes. Do you think anything changes? Of course not, the compiler still accepts the illegal code with the same warning. I sometimes wonder what Disable Language Extensions actually does...

What parts of C++ are / aren't supported with Brew (MP)?

Hi I'm trying to find out what is and isn't possible with C++ on BrewMP.
Does anybody have first hand experience of using C++ with Brew, specifically BrewMP, and can say if they have managed to get these things working on a device without too much hassle:
static variables/functions
templates
exceptions
casting
etc.
Before in Brew3.X, global and static variables are not supported. However in Brew MP, there is an ELF2MOD tool. With this, you can use global and static varaibles.
See your SDK path such as:
C:\Program Files\Qualcomm\Brew MP SDK\Toolset 7.10 Rev 10.0.1489821\bin
If your global or static data is non-POD (a C++ object, which has to call C++ class constructor), please don't use it. See
https://developer.brewmp.com/forum/using-static-variables-classes-0
Standard C Library (stdc lib, or c runtime) are absolutely prohibited in BrewMP, such as memset and sprintf. Cause: In a general process module with main() entry, those of C runtime are already initialized automatically before user's code calling them. BrewMP mod (mod1) files are dynamically loaded and linked. There are no appropriate time to call initialization, and these MODs should not call C runtime initialization individually.
C++ template functions and template classes: template code instantiation are generted at compile-time, and they don't need any load-time and run-time code initialization. They can be used safely in device.
C++ Exceptions: I didn't tested it. In the default ARM compiler options, exception are not turned on. And the exceptions need the enablement of C++ RTTI.
C++ cast: dynamic_cast is the big problem, because it needs support run-time type identification enabled, and doing type checking at run time. Other casts, such as static_cast, reinterpret_cast, and const_cast, are only a hint for compiler to check at compile-time.
There were some problems with:
Virtual or abstract methods
Static and global variable support
Static initialization of global
objects
Most of them can be solved using custom post-linker. It worked fine for me, hope it`s suitable for you too.

What is wrong with this use of offsetof?

I'm compiling some c++ code in MinGW GCC 4.4.0, and getting warnings with the following form...
warning: invalid access to non-static data member '<membername>' of NULL object
warning: (perhaps the 'offsetof' macro was used incorrectly)
This problem seems familiar - something I've tried to resolve before and failed, I think, but a while ago. The code builds fine in Visual C++, but I haven't built this particular code recently in any other compiler.
The problem code is the following template...
template<typename T>
class c_Align_Of
{
private:
struct c_Test
{
char m_Char;
T m_Test;
};
public:
enum { e_Align = offsetof (c_Test, m_Test) };
};
Obviously I can probably use some conditional compilation to use compiler-specific functions for this, and I believe C++0x will (at long last) make it redundant. But in any case, I cannot see anything wrong with this use of offsetof.
Very pedantically, it's possible that because the T parameter types are sometimes non-POD, so GCC classes c_Test as non-POD and complains (and complains and complains - I'm getting nearly 800 lines of these warnings).
This is naughty by the strict wording of the standard, since non-POD types can break offsetof. However, this kind of non-POD shouldn't be a problem in practice - c_Test will not have a virtual table, and no run-time trickery is needed to find the offset of m_Test.
Besides, even if c_Test had a virtual table, GCC implements the offsetof macro using an intrinsic that is always evaluated at compile-time based on the static layout of that particular type. Providing a tool then whining (sorry, warning) every time it's used just seems silly.
Also, I'm not the only person around here who does this kind of thing...
Answer to legit-uses-of-offsetof question
I do remember having an issue with offsetof for this kind of reason, but I don't think the problem was this template.
Any ideas?
Oops...
The issue is with the c_Test struct being non-POD due to the T type being non-POD. Here's a quote from the GCC manual...
-Wno-invalid-offsetof (C++ and Objective-C++ only)
Suppress warnings from applying the
‘offsetof’ macro to a non-POD type.
According to the 1998 ISO C++
standard, applying ‘offsetof’ to a
non-POD type is undefined. In existing
C++ implementations, however,
‘offsetof’ typically gives meaningful
results even when applied to certain
kinds of non-POD types. (Such as a
simple ‘struct’ that fails to be a POD
type only by virtue of having a
constructor.) This flag is for users
who are aware that they are writing
nonportable code and who have
deliberately chosen to ignore the
warning about it.
The restrictions on ‘offsetof’ may be
relaxed in a future version of the C++
standard.
My problem is that almost all my T types have constructors, and are therefore classed as non-POD. I ignored this point as irrelevant earlier - and of course it should be irrelevant for offsetof in principle. The trouble is that the C++ standard uses the one POD vs. non-POD classification even though there are a number of distinct ways to be non-POD, and the compiler is correct to warn about non-standards-compliant use by default.
My solution for the moment will be the option above to suppress the warning - now I just need to figure out how to tell cmake to use it.