#define related Query - c

I was doing code porting from Linux to Windows. I am using Visual Studio environment. I am stuck with one problem.
There is a function call with 2 parameters for Acquire and Release a semaphore in Windows.
The Linux code has one parameter
Windows:
KeInitializeSpinLock(spinlock,oldIRQL);
Linux
spin_lock_init(spinlock);
I have generic call like which I have to use :
Get_Lock(spinlock);
How do I do this for windows without changing the prototype of Get_Lock ?
I tried the following :
#define Get_Lock(lock) \
KIRQL oldIrql;\
KeAcquireSpinLock(&(lock),&oldIrql);
#define Release_Lock(sync) KeReleaseSpinLock(&(sync),oldIrql)
But the compiler is giving errors .. Basically I want to retain the value of oldIrql because that value is needed for KeReleaseSpinLock
Error
error C2275: 'KIRQL' : illegal use of this type as an expression
error C2146: syntax error : missing ';' before identifier 'oldIrql'
error C2065: 'oldIrql' : undeclared identifier
error C2065: 'oldIrql' : undeclared identifier
error C2065: 'oldIrql' : undeclared identifier
KIRQL is defined as
typedef UCHAR KIRQL
What wrong am I doing here ? Or Is there any other method which is there which can be used without changing the prototype of the Get_Lock and Release_Lock?

The problem is due to Microsoft compiler's only supporting C89 standard, which does not allow the intermingling of code and declarations. Get_Lock() is being called after a line of code (I suspect), which introduces the declaration of oldIrql.
If it is the case that the lock is obtained and released in the same scope always a possible fix (hack) would be to declare KIRQL oldIrql; at the top of the scope where Get_Lock() and Release_Lock() is called, and remove the declaration from Get_Lock().
A tidier solution would be to eliminate the macros and introduce a new struct that defines a lock. For example:
typedef struct _lock
{
#ifdef WIN32
UCHAR oldIrql;
PKSPIN_LOCK sem;
#else
#endif
} lock;
lock* lock_new()
{
lock* result = malloc(sizeof(lock));
/* Perform OS dependent initialisation. */
#ifdef WIN32
#else
#endif
return result;
}
void lock_delete(lock* aLock)
{
/* Perform OS dependent tidy tasks. */
#ifdef WIN32
#else
#endif
free(aLock);
}
void lock_obtain(lock* aLock)
{
/* OS dependent acquire. */
#ifdef WIN32
KeAcquireSpinLock(&aLock->sem, &aLock->oldIrql);
#else
#endif
}
void lock_release(lock* aLock)
{
/* OS dependent release. */
#ifdef WIN32
KeReleaseSpinLock(&aLock->sem, aLock->oldIrql);
#else
#endif
}

I also suspect the reason posted by hmjd. But, in my opinion, the solution can be as follows:
#define Get_Lock(lock) { KIRQL oldIrql; KeAcquireSpinLock(&(lock),&oldIrql);
#define Release_Lock(sync) KeReleaseSpinLock(&(sync),oldIrql) }
But, you need to ensure that Get_Lock & Release_Lock is in same scope which anyway you would be ensuring as per your comments.
The idea is mostly same as that of pthread_cleanup_push & pthread_cleanup_pop. You can refer to the same also.

Related

namespace and extern 'C' compilation errors

I have tried to google the errors but to no avail. Maybe I am searching in the wrong direction.
I am trying to compile a file but when i tired to compiled it, the compiler gave me these errors:
C2059 syntax error: ';'
C2059 syntax error: '}'
C2061 syntax error: identifier 'namespace_name'
C2449 syntax error: found '{' at file scope (missing header?)
In my code.c file:
#ifndef myclass_c
#define myclass_c
#include "classA.h"
#include "classB.h"
#include "conversionLib.h" // no namespace is being used here
namespace namespace_name {
// ... generated codes in C....
}
#endif
In classA.h and in classB.h:
#ifndef myclassA_h // myClassB_h if in classB
#define myclassA_h // myClassB_h if in classB
#include "classC.h" // both classA and classB include classC.h
namespace namespace_name {
#ifdef __cplusplus
extern "C" {
#endif
// ... generated codes in C....
#ifdef __cplusplus
}
#endif
}
#endif
and in classC.h (same for classD.h)
#ifndef myclassC_h // myclassD.h for classD.h
#define myclassC_h // myclassD.h for classD.h
#include "classD.h" // no includes in classD.h
namespace namespace_name {
#ifdef __cplusplus
extern "C" {
#endif
// ... generated codes in C....
#ifdef __cplusplus
}
#endif
}
#endif
what am i doing wrong? or have i missed out something?
Any suggestion would be greatly appreciated.
I apologized if this question/format is confusing.
Thanks in advance
The main problem seems to be, that you use c++ syntax in a .c file.
C does not support namespaces!
It does not make much sense to put a extern "C" function into an namespace. in C++ the compiler does something called 'name mangeling' it actually puts the name space (e.g. the class name, the namespace) and additional information (like function or template parameter) of an identifier into its symbol name that is the input to the linker.
extern "C" tells the C++ Compiler not to do so. so you lose the binding to the surrounding namespace (as well as the possibilities to overload the function).
It may be a nice thought to put the functions in a special namespace if they are included from C++ but on the other hand mostly in C namespaces are build y using a special prefix to the function name. so in C++ you end up with the explicit c++ name space and the implicit function prefix name space.
If you still want a namespace in c++ around your C-Functions you have to include the namespace definition into your #ifdef __cplusplus blocks. (but i do not even know if this is allowed by the C++ standard)

Why is _GNU_SOURCE macro required for pthread_mutexattr_settype() while it is in POSIX/IEEE standard?

I have written a multithread server program in C, which echoes back all the data that a client sends.
Initially, I used poll() function in my program to detect POLLRDHUP event, for that I defined _GNU_SOURCE macro (This event is defined here).
Later I updated my code & removed poll() function, however I forgot to remove _GNU_SOURCE macro.
Now my code is finally complete (and a little long to post, more than 250 lines). Before removing macro I was compiling my program using:
gcc multi_thread_socket_v4.c -Wall -Werror -g -lpthread -o multi_thread_socket
and it worked fine: No errors, no warnings
After I removed the macro definition, and compiled using same command-line, the output of gcc was:
multi_thread_socket_v4.c: In function ‘main’:
multi_thread_socket_v4.c:194: warning: implicit declaration of function ‘pthread_mutexattr_settype’
multi_thread_socket_v4.c:194: error: ‘PTHREAD_MUTEX_ERRORCHECK’ undeclared (first use in this function)
multi_thread_socket_v4.c:194: error: (Each undeclared identifier is reported only once
multi_thread_socket_v4.c:194: error: for each function it appears in.)
I have included all the required libraries as it worked fine initially.
I peeked into pthread.h at /usr/include/pthread.h and found out this:
/* Mutex types. */
enum
{
PTHREAD_MUTEX_TIMED_NP,
PTHREAD_MUTEX_RECURSIVE_NP,
PTHREAD_MUTEX_ERRORCHECK_NP,
PTHREAD_MUTEX_ADAPTIVE_NP
#ifdef __USE_UNIX98
,
PTHREAD_MUTEX_NORMAL = PTHREAD_MUTEX_TIMED_NP,
PTHREAD_MUTEX_RECURSIVE = PTHREAD_MUTEX_RECURSIVE_NP,
PTHREAD_MUTEX_ERRORCHECK = PTHREAD_MUTEX_ERRORCHECK_NP,
PTHREAD_MUTEX_DEFAULT = PTHREAD_MUTEX_NORMAL
#endif
#ifdef __USE_GNU
/* For compatibility. */
, PTHREAD_MUTEX_FAST_NP = PTHREAD_MUTEX_TIMED_NP
#endif
};
and this:
#ifdef __USE_UNIX98
/* Return in *KIND the mutex kind attribute in *ATTR. */
extern int pthread_mutexattr_gettype (__const pthread_mutexattr_t *__restrict
__attr, int *__restrict __kind)
__THROW __nonnull ((1, 2));
/* Set the mutex kind attribute in *ATTR to KIND (either PTHREAD_MUTEX_NORMAL,
PTHREAD_MUTEX_RECURSIVE, PTHREAD_MUTEX_ERRORCHECK, or
PTHREAD_MUTEX_DEFAULT). */
extern int pthread_mutexattr_settype (pthread_mutexattr_t *__attr, int __kind)
__THROW __nonnull ((1));
I checked out here to check if __USE_UNIX98 is a feature test macro, but it was not there.
So please help me understanding the reasons for the error, because the function & the macro where gcc shows error are defined in POSIX standard. I do not know what more info regarding my problem will be required so please tell me, I will update my question.
You should use
#define _POSIX_C_SOURCE 200112L
if you want to use POSIX features such as pthread_mutexattr_settype ... see http://pubs.opengroup.org/onlinepubs/007904975/functions/xsh_chap02_02.html
Another possibility is
#define _XOPEN_SOURCE 700
See http://man7.org/linux/man-pages/man7/feature_test_macros.7.html and http://pubs.opengroup.org/onlinepubs/9699919799/
Setting _GNU_SOURCE includes POSIX and lots of other definitions.
P.S. I would expect that including <pthread.h> includes <features.h>, which by default defines _POSIX_C_SOURCE as 200112L, but it's possible that you have defined something that overrides that ... see /usr/include/features.h on your system for details of the symbols and their usage.
It doesn't, your problem likely lies elsewhere.
I just compiled a trivial program with the following content:
#include <pthread.h>
int main(int argc, char **argv)
{
pthread_mutexattr_t attr;
pthread_mutexattr_init(&attr);
pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_ERRORCHECK);
return 0;
}
This compiles perfectly with gcc -pthread -Wall -Werror a.c.
It's possible that another part of your program causes this, by eg. doing something silly like defining _PTHREAD_H, or some other minor sabotage.
You might want to try to get a minimal test case by using a tool like delta or creduce, which will probably make the problem evident.
When you're using old libraries (e.g. 2.1.x) you should use
#define __USE_UNIX98
Using a macro beginning with "__" it's not usually a good idea, but sometimes it's the only way... see also this discussion

extern "C" error #2040: expected an identifier

I still struggling to compile a C console application, the compiling procedure still failing with the error below:
"Main.c", line 51: error #2040: expected an identifier
extern "C" void TreatReceivedSignal( int NoSignal ) ;
^
1 error detected in the compilation of "Main.c".
gmake: *** [Main.o] Error 2
below the declaration of the extern method on the C code :
extern "C" void TreatReceivedSignal( int NoSignal ) ;
I am using HP-UX aCC compiler [HP C/aC++ B3910B A.06.26], also I switched on the compilation flag -Ae to enable C99 support.
Seems that the compiler cannot recognize the 'extern "C"' as C reserved word, may some other compilation flag need to be set.
Any idea please that can solve this kind of issue?
Thank you very much in advance.
Regards
The extern "C" construct is a C++ specific thing, it can't be used in C. And the compiler treats your source file as a C source file since it has the extension .c.
The most common thing to do is to use the preprocessor to conditionally add this for C++ compilations:
#ifdef __cplusplus
extern "C" {
#endif
/* Standard C prototypes */
#ifdef __cplusplus
}
#endif

How can I define KdPrint to DbgPrint?

I am trying to write macros for universal debugging.
How to define KdPrint to DbgPrint?
I am trying like this
#define KdPrint(x) do{DbgPrint x;}while(0)
In driver code
KdPrint(("Driver entry")); // normal syntax for KdPrint.
DbgPrint("Driver entry"); // normal syntax for DbgPrint.
if I compile I am getting error 4013:
'KdPrint' undefined; assuming extern returning int"
#define KdPrint(x) do { DbgPrint(x); } while (0)
...
KdPrint("Driver entry");

C2059 syntax error using declspec macro for one function; compiles fine without it

I've making a shared library (cross-platform), but when trying to compile the Windows build I'm encountering the error:
secure_string.h(43) : error C2059: syntax error : 'type'
This is in regards to the SECURESTRING_API macro. It doesn't complain about the two usages in strlcpy and strlcat, but when trying to use it for 'str_from_last' it generates the above error.
If I remove it, it compiles fine, but the function then isn't exported from the DLL, making it quite useless!
A Google search has yielded no (relevant) results; has anyone encountered this before? I've tested on both Visual Studio 2008 and 2010, and the result is identical. The source file includes string.h and then this file - nothing else.
Header file:
#ifndef SECURE_STRING_H
#define SECURE_STRING_H
/* Provide MS Builds with import/export functionality
* BUILD_SECURE_STRING should be added to project preprocessor macros */
#if _WIN32
# if defined(BUILD_SECURE_STRING)
# define SECURESTRING_API __declspec(dllexport)
# else
# define SECURESTRING_API __declspec(dllimport)
# endif
#else
# define SECURESTRING_API
#endif
/* Windows on the whole, and glibc do not have/support strlc[at|py]
* This will almost certainly need revision for proper cross-platform checks */
#if _WIN32 || __GLIBC__ || !defined(HAVE_STRLCPY)
size_t SECURESTRING_API strlcat(char* dst, const char* src, size_t size);
size_t SECURESTRING_API strlcpy(char* dst, const char* src, size_t size);
#else
# define HAVE_STRLCPY 1
#endif
/* In case the active project has yet to include headers for 'BOOL' */
#ifndef BOOL
# define BOOL int
# define TRUE 1
# define FALSE 0
#endif
/*
| Locates 'search' within 'source', and if found, returns either the
| character itself, or the character after it if 'return_from_after_found'
| is TRUE.
| If it is not found, or any parameter is invalid, a NULL pointer is returned.
*/
char* SECURESTRING_API
str_from_last(char* source,
char search,
BOOL return_from_after_found);
#endif /* SECURE_STRING_H */
#if _WIN32
Are you sure you're entering this? I would:
#if defined(WIN32)
EDIT: That looks OK but this I think is it:
move the SECURESTRING_API before the return type (char*):
SECURESTRING_API char*
With this change your code compiles for me under VS2010 and MSDN confirms that is the required order:
The decl-specifier-seq should contain, among other things, a base type
(e.g. int, float, a typedef, or a class name), a storage class (e.g.
static, extern), or the __declspec extension. The init-declarator-list
should contain, among other things, the pointer part of
declarations.

Resources