Retro video games delivered to your door every month!
Click above to get retro games delivered to your door ever month!
X-Hacker.org- Watcom C/C++ User's Guide - watcom c/c++ supports the __declspec keyword for compatibility with http://www.X-Hacker.org [<<Previous Entry] [^^Up^^] [Next Entry>>] [Menu] [About The Guide]
Watcom C/C++ supports the __declspec keyword for compatibility with
Microsoft C++.  The __declspec keyword is used to modify storage-class
attributes of functions and/or data.

__declspec( thread )
    is used to define thread local storage (TLS).  TLS is the mechanism by
    which each thread in a multithreaded process allocates storage for
    thread-specific data.  In standard multithreaded programs, data is
    shared among all threads of a given process, whereas thread local
    storage is the mechanism for allocating per-thread data.

    Example:

         __declspec(thread) static int tls_data = 0;

    The following rules apply to the use of the thread attribute.

     .  The thread attribute can be used with data and objects only.
     .  You can specify the thread attribute only on data items with static
        storage duration.  This includes global data objects (both static
        and extern ), local static objects, and static data members of
        classes.  Automatic data objects cannot be declared with the thread
        attribute.  The following example illustrates this error:

        Example:

             #define TLS __declspec( thread )
             void func1()
             {
                 TLS int tls_data;           // Wrong!
             }

             int func2( TLS int tls_data )   // Wrong!
             {
                 return tls_data;
             }
     .  The thread attribute must be used for both the declaration and the
        definition of a thread local object, whether the declaration and
        definition occur in the same file or separate files.  The following
        example illustrates this error:

        Example:

             #define TLS __declspec( thread )
             extern int tls_data;    // This generates an error, because the
             TLS    int tls_data;    // declaration and the definition
        differ.
     .  Classes cannot use the thread attribute.  However, you can
        instantiate class objects with the thread attribute, as long as the
        objects do not need to be constructed or destructed.  For example,
        the following code generates an error:

        Example:

             #define TLS __declspec( thread )
             TLS class A     // Wrong! Classes are not objects
             {
                 // Code
             };
             A AObject;

        Because the declaration of objects that use the thread attribute is
        permitted, these two examples are semantically equivalent:

        Example:

             #define TLS __declspec( thread )
             TLS class B
             {
                 // Code
             } BObject;      // Okay! BObject declared thread local.

             class C
             {
                 // Code
             };
             TLS C CObject;  // Okay! CObject declared thread local.
     .  Standard C permits initialization of an object or variable with an
        expression involving a reference to itself, but only for objects of
        non-static extent.  Although C++ normally permits such dynamic
        initialization of an object with an expression involving a reference
        to itself, this type of initialization is not permitted with thread
        local objects.

        Example:

             #define TLS  __declspec( thread )
             TLS int tls_i = tls_i;            // C and C++ error
             int j = j;                        // Okay in C++; C error
             TLS int tls_k = sizeof( tls_k );  // Okay in C and C++

        Note that a sizeof expression that includes the object being
        initialized does not constitute a reference to itself and is allowed
        in C and C++.

__declspec( naked )
    indicates to the code generator that no prologue or epilogue sequence is
    to be generated for a function.  Any statements other than "_asm"
    directives or auxiliary pragmas are not compiled.  _asm Essentially, the
    compiler will emit a "label" with the specified function name into the
    code.

    Example:

         #include <stdio.h>

         int __declspec( naked ) foo( int x )
         {
             _asm {
         #if defined(__386__)
                 inc eax
         #else
                 inc ax
         #endif
                 ret
             }
         }

         void main()
         {
             printf( "%d\n", foo( 1 ) );
         }

    The following rules apply to the use of the naked attribute.

     .  The naked attribute cannot be used in a data declaration.  The
        following declaration would be flagged in error.

        Example:

             __declspec(naked) static int data_object = 0;


__declspec( dllimport )
    is used to declare functions, data and objects imported from a DLL.

    Example:

         #define DLLImport __declspec(dllimport)

         DLLImport void dll_func();
         DLLImport int  dll_data;

    Functions, data and objects are exported from a DLL by use of
    __declspec(export), the __export keyword (for which __declspec(export)
    is the replacement), or through linker "EXPORT" directives.

__declspec( dllexport )
    is used to declare functions, data and objects exported from a DLL.
     Declaring functions as dllexport eliminates the need for linker
    "EXPORT" directives.  The __declspec(dllexport) attribute is a
    replacement for the __export keyword.

__declspec( __pragma( "string" ) )
    is used to declare functions which adhere to the conventions described
    by the pragma identified by "string".

    Example:

         #include <stdio.h>

         #pragma aux my_stdcall "_*" \
                 parm routine [] \
                 value struct struct caller [] \
                 modify [eax ecx edx];

         struct list {
             struct list *next;
             int         value;
             float       flt_value;
         };

         #define STDCALL __declspec( __pragma("my_stdcall") )

         STDCALL struct list foo( int x, char *y, double z );

         void main()
         {
             int a = 1;
             char *b = "Hello there";
             double c = 3.1415926;
             struct list t;

             t = foo( a, b, c );
             printf( "%d\n", t.value );
         }


         struct list foo( int x, char *y, double z )
         {
             struct list tmp;

             printf( "%s\n", y );
             tmp.next = NULL;
             tmp.value = x;
             tmp.flt_value = z;
             return( tmp );
         }

    The __pragma modifier is supported by Watcom C++ only.

__declspec( __cdecl )
    is used to declare functions which conform to the Microsoft compiler
    calling convention.

__declspec( __pascal )
    is used to declare functions which conform to the OS/2 1.x and Windows
    3.x calling convention.

__declspec( __fortran )
    is used to declare functions which conform to the __fortran calling
    convention.

    Example:
         #include <stdio.h>

         #define DLLFunc __declspec(dllimport __fortran)
         #define DLLData __declspec(dllimport)

         #ifdef __cplusplus
         extern "C" {
         #endif

         DLLFunc int  dll_func( int, int, int );
         DLLData int  dll_data;

         #ifdef __cplusplus
         };
         #endif

         void main()
         {
           printf( "%d %d\n", dll_func( 1,2,3 ), dll_data );
         }


__declspec( __stdcall )
    is used to declare functions which conform to the 32-bit Win32
    "standard" calling convention.

    Example:

         #include <stdio.h>

         #define DLLFunc __declspec(dllimport _stdcall)
         #define DLLData __declspec(dllimport)

         DLLFunc int  dll_func( int, int, int );
         DLLData int  dll_data;

         void main()
         {
           printf( "%d %d\n", dll_func( 1,2,3 ), dll_data );
         }

__declspec( __syscall )
    is used to declare functions which conform to the 32-bit OS/2 __syscall
    calling convention.

Online resources provided by: http://www.X-Hacker.org --- NG 2 HTML conversion by Dave Pearson