Does MSVC support C++11-style attributes instead of __declspec? - c++

I know that C++11-style attributes support vendor-specific attributes that are prefixed by a namespace. Both GCC and Clang support various attributes with the prefix either gnu:: (gcc and clang) or clang:: (clang only) which correspond to an equivalent __attribute__((...)) syntax.
The documentation for MSVC attributes shows that it supports the standard attributes, as well as a gsl:: attribute -- but it makes no mention of backwards-compatibility for __declspec attributes.
I'd expect something like __declspec(noinline) to have an attribute representation of [[msvc::noinline]] -- but I can't seem to find any documentation on this.
So my question is, does MSVC support __declspec as C++11-style attributes at all?
If it doesn't, would anyone happen to know they don't?
The original rationale for C++'s attributes was to abstract the various compiler-specific __attribute__ and __declspec features, so it would be weird if it's still not supported 9 years after standardization.

There is no [[msvc::noinline]] or other __declspec equivalents as of VC++ 2019.
From the official MSVC documentation for Attributes in C++:
In Visual C++, you can use the [[deprecated]] attribute instead of using declspec(deprecated) and the attribute will be recognized by any conforming compiler. For all other declspec parameters such as dllimport and dllexport, there is as yet no attribute equivalent so you must continue to use declspec syntax.
[ EDIT ]   Information on why [[attributes]] are not more widely used in VC++, perhaps replacing __declspec entirely, is surprisingly scarce. The closest to an authoritative source that I found were these comments in the reddit thread C++ attribute specifier sequence, MSVC and me:
spongo2 - MSVC Dev Manager
We just had a rousing team room discussion on this topic. We definitely see the use case here and it's interesting but we're wondering if the fact that the number of places one can put attributes is large and growing would lead to surprising behavior.
STL - MSVC STL Dev
I would use [[msvc::kitty]] instead of __declspec(kitty) in the STL, in order to make our sources more palatable to other front-ends. I already switched to using [[noreturn]] instead of __declspec(noreturn) because that one's Standard.
My reading is that what's holding back a wider adoption is the concern about scopes of attributes vs. __declspec, and backwards compatibility in general.

According to Attributes in C++ the only __declspec() with an attribute replacement is [[deprecated]], for all other __declspec() modifiers you must continue to use __declspec.

Related

How can I know if C++ compiler make thread-safe static object code?

In GCC, local static variable is thread-safe (by special function__cxa_guard_acquire) unless -fno-threadsafe-statics compiler option is given.
Similarly, MSVC 2015 and onward version support the same feature and can be disabled by /Zc:threadSafeInit-.
Is there any macro or other features, like __EXCEPTIONS or __GXX_RTTI to check on compilation stage if such features are enabled or not? I think checking __cplusplus or _MSC_VER won't help.
Looks like there is one define __cpp_threadsafe_static_init.
SD-6: SG10 Feature Test Recommendations:
C++11 features
Significant features of C++11
Doc. No. Title Primary Section Macro name Value Header
N2660 Dynamic Initialization and Destruction with Concurrency 3.6 __cpp_threadsafe_static_init 200806 predefined
CLang - http://clang.llvm.org/cxx_status.html#ts (github.com)
GCC - https://gcc.gnu.org/projects/cxx-status.html
MSVC - Feature request under investigation https://developercommunity.visualstudio.com/content/problem/96337/feature-request-cpp-threadsafe-static-init.html
Useful on cppreference.com:
Feature Test Recommendations
C++ compiler support

gcc inlined assembly jmp address; Naked functions

I can jmp to an address using Visual Studio 2012.. When it comes to gcc/mingw, I cannot tell if my jump is correct.
How can I jump to an address in gcc?
I tried:
__declspec(naked) void DXHook_D3DPERF_BeginEvent()
{
#ifdef _MSC_VER //If using visual studio..
__asm{jmp[Addr]} //Jump to: Address stored in Addr.
#else //else using gcc..
__asm("jmp *%0"
: /*No Outputs*/
: "r" (Addr)
: "%eax");
#endif
}
Is this correct? Also, is there a way to get gcc to stop bothering me about:
warning: 'naked' attribute directive ignored.
Why does it ignore my naked attribute?
TL;DR In GCC, this is only available on: ARM, AVR, MCORE, MSP430, NDS32, RL78, RX and SPU ports
It is NOT available on x86.
Workaround (proposed by Brendon in the comments).
Full answer
(The rest of this answer assumes you are using a supported target)
That is because you are using the Windows attribute syntax, __declspec with GCC.
Quote from the MSDN reference on __declspec:
The extended attribute syntax simplifies and standardizes Microsoft-specific extensions to the C and C++ languages.
You should use the GCC function attribute syntax instead or in parallel.
Please also note the following quote from this GCC article:
Note: The semantics are not the same between Windows and this GCC
feature - for example, __declspec(dllexport) void (*foo)(void) and
void (__declspec(dllexport) *foo)(void) mean quite different things
whereas this generates a warning about not being able to apply
attributes to non-types on GCC.
So there could also be an issue with the way you are using the __declspec syntax in GCC (if it even supports it).
You should also note that the only __declspec attribute that GCC states it supports is the __declspec(dllexport) (as stated in the already mentioned GCC attribute syntax link).
So let's look for a generic solution to your problem but first we will need to read about the actual GCC attribute syntax and find the following:
An attribute specifier list may appear immediately before a declarator
(other than the first) in a comma-separated list of declarators in a
declaration of more than one identifier using a single list of
specifiers and qualifiers. Such attribute specifiers apply only to the
identifier before whose declarator they appear. For example, in
__attribute__((noreturn)) void d0 (void),
__attribute__((format(printf, 1, 2))) d1 (const char *, ...),
d2 (void)
the noreturn attribute applies to all the functions declared; the
format attribute only applies to d1.
So the solution to your problem would be something like the following:
#ifdef __GNUC__
#define ATTRIBUTE_NAKED __attribute__((naked))
#else
#define ATTRIBUTE_NAKED __declspec(naked)
#endif
ATTRIBUTE_NAKED void DXHook_D3DPERF_BeginEvent()
{
#ifdef _MSC_VER //If using visual studio..
__asm{jmp[Addr]} //Jump to: Address stored in Addr.
#else //else using gcc..
__asm("jmp *%0"
: /*No Outputs*/
: "r" (Addr)
: "%eax");
#endif
}
Edit:
It is important to note that this attribute is platform specific. And I quote:
naked
This attribute is available on the ARM, AVR, MCORE, MSP430, NDS32, RL78, RX and SPU ports. It allows the compiler to construct the
requisite function declaration, while allowing the body of the
function to be assembly code. The specified function will not have
prologue/epilogue sequences generated by the compiler. Only basic asm
statements can safely be included in naked functions (see Basic Asm).
While using extended asm or a mixture of basic asm and C code may
appear to work, they cannot be depended upon to work reliably and are
not supported.
Quoted from the GCC documentation on function attributes.
Side note
Possible further reading on clang attributes could help (mostly compatible with GCC) but these comments seem to suggest a desire to match GCC behavior.
To do the equivalent of the Visual C++ code, implement it entirely in assembly either in a separate file or in a top level (not in a function) asm statement.

Where can I find information on the C++ [[deprecated]] attribute

I got sent a link describing a [[deprecated]] attribute in C++11. This sound pretty convenient, and I would like to have more information about it - which compilers support it, full documentation on it, etc.
I spent 20 minutes or so googling around, but apart from the linked website, I couldn't find infos on this anywhere. Partly, this was complicated by other uses of the word "deprecated" in connection with C++11, and search engines not recognizing [[. I didn't find this in draft standards linked to in various SO answers, either. I don't have access to the full, paid, standard.
Does anybody have more information about this [[deprecated]] attribute?
P.S.: If you're curious, I'd use this as a better alternative to https://stackoverflow.com/a/295229/599884
The [[deprecated]] attribute has made its way into the draft of C++14 (see section 7.6.5 [dcl.attr.deprecated] of the October 2013 draft).
The attribute-token deprecated can be used to mark names and entities whose use is still allowed, but is discouraged for some reason.
For example, the following function foo is deprecated:
[[deprecated]]
void foo(int);
It is possible to provide a message that describes why the name or entity was deprecated:
[[deprecated("Replaced by bar, which has an improved interface")]]
void foo(int);
The message must be a string literal.
First, things in [[]] are not keywords; they are attributes.
Second, there is no [[deprecated]] attribute defined by the C++11 standard. The link you're referring to is either in error or referring to a specific compiler (C++Builder, perhaps?) that implements this attribute.
Attributes are (usually) compiler specific. Like #pragmas, compilers are supposed to ignore any attribute they don't support.

Compiler independent C++ properties

Microsoft Visual C++ compiler has the property declaration construction
__declspec( property( get=get_func_name, put=put_func_name ) )
Is there a compiler independent version of Microsoft C++ __declspec(property(...)) or another analogs?
No.
As usual, an identifier preceded by __ is reserved to the compiler. In C++03 you have __cpluscplus (to identify C++ vs C), __FILE__ and __LINE__. All those are preprocessor entities.
In C++0x, the difference is blurred by the introduction of the __attribute__ word which is the first I know of that has semantics value, but it still does not do what you're looking for.
EDIT: Addressing #James spot on comment.
As Nicola Musatti says, there was a Borland proposal, primarily because Borland Delphi uses Properties heavily, and C++Builder (their C++ 'equivalent' to Delphi) therefore requires it.
In C++Builder, the code looks a bit like this.
__property __int64 Size = {read=GetSize, write=SetSize};
No. Similar mechanisms were proposed to the C++ standard committee but none was ever accepted (Here is one such proposal from Borland).
I've seen template based toy implementations, but they tend to be too inconvenient to be of practical use, the major problems being:
As nested class instances are not members of the enclosing class (as are Java inner class instances), you have to explicitly "connect" a property to its enclosing class, which makes declaration and initialization cumbersome.
There is no way to call function-like entities without parentheses, so you cannot invoke a custom-made property as if you were accessing a variable.

strcmpi renamed to _strcmpi?

In MSVC++, there's a function strcmpi for case-insensitive C-string comparisons.
When you try and use it, it goes,
This POSIX function is deprecated beginning in Visual C++ 2005. Use the ISO C++ conformant _stricmp instead.
What I don't see is why does ISO not want MSVC++ to use strcmpi, and why is _stricmp the preferred way, and why would they bother to rename the function, and how is a function beginning with an underscore ISO conformant. I know there must be a reason for all this, and I'm suspecting its because strcmpi is non-standard, and perhaps ISO wants non-standard extensions to begin with an _underscore?
ISO C reserves certain identifiers for future expansion (see here), including anything that starts with "str".
IMNSHO, this is Microsoft's way of saying "Do not put Unix software on Windows machines". There are several frustrating aspects to the problem:
strcmpi() is not a POSIX function - the relevant functions are defined in <strings.h> and are called strcasecmp() etc.
Even if you explicitly request support for POSIX functions, Microsoft thinks that you may not use the POSIX names but must prefix them with the wretched underscore.
AFAIK, there isn't a way of overriding the MSVC compiler's view on the issue.
That said, the GCC tool chain gets a bit stroppy about some functions - mktemp() et al. However, it does compile and link successfully, despite the warnings (which are justified).
I note that MSVC also has a bee in its bonnet about snprintf() et al. If their function conformed to the C99 standard (along with the rest of the compiler), then there would never be any risk of an overflow - the standard requires null termination, contrary to the claims of Microsoft.
I haven't got a really good solution to this problem - I'm not sure there is one. One possibility is to create a header (or set of headers) to map all the actual POSIX names to Microsoft's misinterpretation of them. Another is two create a library of trivial functions with the correct POSIX name that each call down onto the Microsoft version of the name (giving you a massive collection of four-line functions - the declarator line, an open brace, a close brace, and a return statement that invokes the Microsoft variant of the POSIX function name.
It's funny how the Microsoft API calls, which also pollute the user's name space, are not deprecated or renamed.
Names begining witth an underscore and a lower case letter are reserved by the C++ Standard for the C++ implementation, if they are declared in the global namespace. This stops them from clashing with similar names in your own code, which must not use this naming convention.
strcmpi goes away altogether in Visual C++ 2008, so you should definitely heed the deprecation if you ever intend to upgrade.
The _ doesn't make the function ISO standard, it's just that functions beginning with _ are safer to add as the language evolves because that's one of the parts of the namespace reserved for the language to use.
According to Microsoft's documentation for _stricmp, it sounds like strcmpi has some practices that result in some unintuitive orderings (including normalizing to lower case instead of simply treating case as irrelevant). Sounds like _stricmp takes more pains to do what one would naturally expect.