187

I have seen instances of __declspec in the code that I am reading. What is it? And when would I need to use this construct?

kvantour
  • 25,269
  • 4
  • 47
  • 72
Scott J
  • 3,402
  • 4
  • 22
  • 14
  • 8
    If you were unlucky and moved from Linux to Windows, you might waste time trying to figure out why your DLLs wouldn't work, until you find that you have to add `__declspec(dllexport)` before each function in your library – SomethingSomething May 14 '20 at 08:37

6 Answers6

100

This is a Microsoft specific extension to the C++ language which allows you to attribute a type or function with storage class information.

Documentation

__declspec (C++)

Mark Benningfield
  • 2,800
  • 9
  • 31
  • 31
JaredPar
  • 733,204
  • 149
  • 1,241
  • 1,454
  • 35
    Thanks - but what would I use it for? – Scott J Feb 17 '10 at 21:45
  • 6
    For declaring COM interfaces and classes, for example, you use __declspec(uuid), for exporting functions sans a DEF file you use __declspec(dllexport), etc. The full list is quite long. – Seva Alekseyev Feb 17 '10 at 21:49
  • 2
    @ScottJ I constantly use it for properties: __declspec(property(get=X put=X)) data-type identifier. MSDN has more details of course. As a "C# to C/C++ programmer" it's a bliss! – MasterMastic Aug 14 '12 at 21:29
68

The canonical examples are __declspec(dllimport) and __declspec(dllexport), which instruct the linker to import and export (respectively) a symbol from or to a DLL.

// header
__declspec(dllimport) void foo();


// code - this calls foo() somewhere in a DLL
foo();

(__declspec(..) just wraps up Microsoft's specific stuff - to achieve compatibility, one would usually wrap it away with macros)

Robino
  • 4,530
  • 3
  • 37
  • 40
Alexander Gessler
  • 45,603
  • 7
  • 82
  • 122
  • 10
    @tetris, you don't know from the code. The decision is made by the linker, who will pick the first `.lib` it finds that has a matching exported symbol. – Euro Micelli Nov 01 '13 at 10:57
27

It is mostly used for importing symbols from / exporting symbols to a shared library (DLL). Both Visual C++ and GCC compilers support __declspec(dllimport) and __declspec(dllexport). Other uses (some Microsoft-only) are documented in the MSDN.

K DawG
  • 13,287
  • 9
  • 35
  • 66
AndiDog
  • 68,631
  • 21
  • 159
  • 205
16

Another example to illustrate the __declspec keyword:

When you are writing a Windows Kernel Driver, sometimes you want to write your own prolog/epilog code sequences using inline assembler code, so you could declare your function with the naked attribute.

__declspec( naked ) int func( formal_parameters ) {}

Or

#define Naked __declspec( naked )
Naked int func( formal_parameters ) {}

Please refer to naked (C++)

DanielV
  • 2,076
  • 2
  • 40
  • 61
HackNone
  • 504
  • 6
  • 12
9

Essentially, it's the way Microsoft introduces its C++ extensions so that they won't conflict with future extensions of standard C++. With __declspec, you can attribute a function or class; the exact meaning varies depending on the nature of __declspec. __declspec(naked), for example, suppresses prolog/epilog generation (for interrupt handlers, embeddable code, etc), __declspec(thread) makes a variable thread-local, and so on.

The full list of __declspec attributes is available on MSDN, and varies by compiler version and platform.

Seva Alekseyev
  • 59,826
  • 25
  • 160
  • 281
  • 3
    Considering non-microsoft compilers like `GCC 4.2`, that offer alternative in addition to their `__attribute__ ((dllexport))` to `__declspec(dllexport)`, is it fair to call `__declspec`, a Microsoft-only extension? – user2338150 Jul 04 '17 at 06:03
  • I don't know of any other compilers that would support it, so yes, it's Microsoft only. – Seva Alekseyev Nov 08 '20 at 18:07
  • Borland's C++Builder also uses __declspec. – David Jul 09 '22 at 02:47
2

I know it's been eight years but I wanted to share this piece of code found in MRuby that shows how __declspec() can bee used at the same level as the export keyword.

/** Declare a public MRuby API function. */
#if defined(MRB_BUILD_AS_DLL)
#if defined(MRB_CORE) || defined(MRB_LIB)
# define MRB_API __declspec(dllexport)
#else
# define MRB_API __declspec(dllimport)
#endif
#else
# define MRB_API extern
#endif