Visual C++ 2010 solution-wide macros with parameters - c++

I'm trying to compile some source code with Visual C++ 2010 Express. The code was written for GCC, and contains attributes like this:
struct something {
...
} __attribute__((packed));
Since this is not standard C++ syntax, Visual C++ doesn't recognize it. With this macro prior to the struct declaration, it works fine:
#define __attribute__(p)
But I don't want to alter the files. I created a new property sheet (GccCompat), and went to Preprocessor Definitions, and added the macro, like this:
__attribute__(p)
or like this:
__attribute__(p)=
But it doesn't work. It's simply not called. If I define just __attribute__ (without parameters) in the same location, the macro is correctly defined. Note that the command line that is generated looks fine (the macros with parameters are passed exactly the same as the ones without), but the compiler seems to ignore it. So, how can I globally define my macro with a parameter?

It might be impossible, at least that way. Notice that Microsoft's documentation of the /D option doesn't specify a syntax for macros that take arguments.

Defining macros in the IDE is generally focused on the nature of creating a /D:CPP_TOKEN flag for the compiler, i.e. #define CPP_TOKEN.
In the advanced compiler settings you may be able to define such a macro as /D:"attributes(p)=/nothing/" or something like that. Just open the VS command prompt and see what it says. GCC 4.2 will allow something like that (using it's -D switch), but I don't have MSVC10 handy.

Related

VSCode C++ Intellisense can't discern C++20 features

I try to run codes like
#include <string>
#include <iostream>
int main() {
std::string str = "This is a string";
std::cout << str.starts_with("name");
}
But intellisense will give out an error
"std::__cxx11::basic_string<char, std::char_traits,
std::allocator>" has no member "starts_with" C/C++(135) [6,9]
And It still can be build and produce a correct result.
Also it can find implementation in header file.
But the macro __cplusplus is defined as 201703L
I've already added a command -std=c++20 when building, why this happened?
Compiler: minGW 11.2 compiled by msys2
Assuming you are using Microsoft's C/C++ extension, you must configure the extension to use C++ 20 standard for intellisense.
The easiest way to do this is to add the line "C_Cpp.default.cppStandard": "c++20" to your settings.json file. You can also find the setting in the GUI under the name "Cpp Standard". Selecting c++20 from its dropdown will achieve the same result.
Note that this setting is, by default, set as a global user defaults. You can configure it per-workspace by selecting the Workspace tab in the settings GUI and changing that Cpp Standard dropdown to c++20.
As for why adding the -std=c++20 flag didn't work: -std=c++20 just tells your compiler which standard to use to build your code. 'Intellisense' does not receive this flag because it is a separate tool from the compiler and is therefore not required to support all the standards the compiler supports. It may support less even, although Intellisense tools usually support as current a standard as possible. Therefore the language standard for Intellisense must be configured separately from the compiler (in this case).
Final Note: After changing the setting, try closing and re-opening VS Code. In my experience changing the language standard setting can cause some weirdness to happen. Closing and re-opening VS Code seems to ensure the setting changes take full effect.

Distinguish between Clang CL and MSVC CL

There is CLang-CL which is a drop-in replacement for MSVC's CL.
Does anyone know how to distinguish if my code is currently compiled by clang-cl or msvc's cl? Without passing any extra defined macros on command line.
Using
#ifdef _MSC_VER
//.....
#endif
doesn't work, both compilers define _MSC_VER.
Also in regular CLang on Linux (Windows too) it was possible to do clang -dM -E - < /dev/null which dumps all defined macros. But clang-cl and msvc-cl both don't have such option to dump all defined macros as far as I know, so I don't know of a way to see a difference in list of defined macros for both compilers to figure out which macro to use to distinguish between these compilers.
The macro you're looking for is __clang__.
Note that the regular Clang (not only Clang-CL) also defines it, so you want to check for both __clang__ and _MSC_VER at the same time.

C++ source_annotation_attribute

When browsing the source of the open source .NET Framework 4.7 I stumbled across the C++ header sal.h and found a line of code saying [source_annotation_attribute( SA( Method ) )] which seems to be similar to attributes and the AttributesUsage class in C#.
Now I know that generally, there are no user defined attributes in C++ as there are in C#, and my first guess was that [source_annotation_attribute( SA( Method ) )] is just a macro, but it is neither defined in sal.h nor in any other headers, since sal.h does not #include any.
My next guess is that [source_annotation_attribute] is actually built in the MSVC, just like for e.g. [[noreturn]] attribute.
I would be glad if somebody could shed some light on what it actually is and if I can declare my own attributes similar to that, if it is not built into the compiler.
If you want to see for your self, the particular file is \Source\externalapis\legacy\vctools\vc12\inc\vc\sal.h and the attribute occurs (among others) in line 1934.
Here is an example on the usage in sal.h:
[source_annotation_attribute( SA( Method ) )]
struct __M_
{
#ifdef __cplusplus // [
__M_();
#endif // ]
int __d_;
};
typedef struct __M_ __M_;
Many thanks in advance.
To conclude what #VTT has already said, it looks like the source_annotation_attribute is a compiler inbuilt construct, which is shipped as part of a Microsoft extension to C++
(even if it is not mentioned there because it is an implementation detail, meant for internal use only) that is valid only when compiled with the compiler switch /Ze
What adds to this is the fact that Microsofts SAL is built in deeply in Visual Studio
i.e.
Build -> Run Code Analysis on Solution
and since Visual Studio (obviously) uses their MSVC compiler, it is not too implausible that Microsoft would not build any internal constructs like this in their compilers.

GCC - "has initializer but incomplete type" error when using macros for function attributes

I have a few header files with some simple glorified structs with just pure virtual methods defined within them. The code compiles fine on Windows with Visual Studio 2015, but GCC is getting stuck. First, the code:
Code Listing
namespace CustomUtils
{
interface API_ABSTRACT overriden
{
virtual int GetStatus() const = 0;
};
}
In an imported header file, interface is just defined as a stuct:
#define interface struct
And API_ABSTRACT is just a macro for nothing:
#define API_ABSTRACT
The interface typedef is part of inherited code I have no control over, and the API_ABSTRACT is in place so that I can define custom attributes in Windows and Linux to limit which API functions I export. While this builds in VS2015, on Linux, I get a build error:
error: variable 'API_ABSTRACT CustomUtils::overridden' has initializer but incomplete type
If I change the line:
interface API_ABSTRACT overriden
To what I presume it is being translated to:
struct overriden
The code will compile fine in Linux. I've tried compiling with gcc -E -dD to have the post-"pre-processed" source rendered to screen to see the typedef and #define substitutions, but it seems to only show the output for .cpp files, and not header (.h) files.
The Question
Why won't this code work when attempting to compile with GCC?
Thank you.
Edit #1
The output from gcc -E shows the offending line to be:
struct API_ABSTRACT overriden
So it seems the culprit is the API_ABSTRACT macro, which evaluates to nothing.
API_ABSTRACT was not defined anywhere (the corresponding file was not included). The way to check it is through tell-tale gcc -E:
struct API_ABSTRACT overriden
With -E, gcc would show preprocessed output, and having API_ABSTRACT in plain sight there means preprocessor knew nothing of it.
When C++ compiler have seen this construct (struct API_ABSTRACT overridden), it thought (according to grammar and if you grant compilers cognizance) that overriden is a variable of type API_ABSTRACT. Followed by braces, it turned the construct into initialization of said variable. However, type API_ABSTRACT was never defined, so compiler complained about initializing a variable of incomplete type.

How to know where a certain macro is defined in Visual Studio

I currently have a visual studio project that uses DirectX. There are some macros in the code such as
__range(0, m_lBatchSize) LONG m_nBatched;
__field_ecount_opt(m_lBatchSize) IMediaSample ** m_ppSamples;
I wanted to know which files these macros are defined in. Normally in Visual Studio I would click goto definition and it would take me to the definitio. It is not taking me anywhere in this case. Does that feature work for macros ? Is there any way for me to find out where this macro is defined ?
my trick is to put
#define __range FOO
in my code, the preprocessor will then say
__range already defined at xxxx.nn