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");
Related
I'm writing a C program that uses a custom logging function to debug my program. Whenever I compile my program as a release version, I want all of my logging functions to be stripped from the code so it won't show up if someone tries to disassemble it.
Take the following example:
#include <stdio.h>
void custom_logging_function(char* message)
{
// Do something here
}
int main()
{
custom_logging_function("Hello world"); // This call should be removed.
return 0;
}
How could I make it so that the custom_logging_function and it's arguments aren't compiled into my program without having to write include guards everywhere throughout my code? Thank you
You can use pre-processor flags, for example:
#include <stdio.h>
#ifdef DEBUG
void custom_logging_function(char* message)
{
// Do something here
}
#else
#define custom_logging_function(x) ((void) 0)
#endif
int main()
{
custom_logging_function("Hello world"); // This call should be removed.
return 0;
}
With this code you will have to tell the "debug" target to define DEBUG, if you want to define something specifically for the "release" target you can replace #ifdef DEBUG with #ifndef NDEBUG and add the NDEBUG flag to the "release" definitions.
Edit:
Changed #define custom_logging_function(x) 0 to #define custom_logging_function(x) ((void) 0) inspired by #JoachimPileborg his answer.
Assuming you only want the logging calls to happen in a debug-build of your application, and not the release build you send to customers, you can still use the preprocessor and conditional compilation for it. It can be made vert simple though by using macros instead of having checks at every call.
Something like this in a heder file:
#ifdef _DEBUG
void custom_logging_function(char* message);
#else
# define custom_logging_function(message) ((void) 0)
#endif
You could use an empty macro body for the release-macro, but that can cause some compilers to give "empty statement" warnings. Instead I use an expression casted to void (to tell the compiler that the result of the expression will not be used). Any smart compiler will not include the expression after optimization.
I have an embedded C source code. In it's definitions, it has a lot of #define lines like following:
#define XNV_SPI_TX(x) st(U1CSR &= 0xFD; U1DBUF = (x);)
any idea what does
st( )
means and does?
I am using IAR as compiler and toolchain.
Thanks to comments, here is what I found:
/* (The while condition below evaluates false without generating a
* constant-controlling-loop type of warning on most compilers.)
*/
#define st(x) do { x } while (__LINE__ == -1)
This construct is used to prevent if/else conditionals show unexpected behavior.
For example if you have something like
#define assign() a=1;b=0;
it would not behave as expected in if/else statement.
I am trying to read a key hit and then stop a code. In C.
#include <conio.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
bool starting()
{
char c;
if (kbhit())
{
c=getch();
if (c=="S"||c=="s")
{
return true;
}
else
{
return false;
}
}
else
{
return false;
}
}
int main()
{
while(!starting)
{
printf("line 1");
delay(100);
}
return 0;
}
Without stdbool.h, it says errors like
syntax error: identifier 'starting',
syntax error: ";"
syntax error: ")"
'starting': undeclared identifier
With stdbool.h, it says file not found. My compiler is the one that comes with Visual Studio 2010.
Any suggestion how to remove this? How can I still use a function that returns a boolean value?
ADDED
sorry! for the short comment added. resolved mostly. Thanks all
Added
More Errors:
After Compiling: it reads:
filename.obj unresolved external symbol _delay referenced in function _main.
What should I do?
stdbool.h is introduced in C99, and Visual Studio doesn't support C99. You can define the types yourself. One possible way is:
typedef int bool;
#define true 1
#define false 0
Three problems at once:
C doesn't know bool as a type of its own, but you can define it (e.g. through stdbool.h or just by using a typedef to any other integral type (usually unsigned char or int; this might be a question of memory usage vs. performance based).
MSVC is known for not having all the std**.h headers, especially older versions. So you most likely just don't have stdbool.h in VS 2010 (the reason for the file not found error).
You're missing brackets in this expression: while(!starting).
I'm trying to use a preprocessor directive in a macro? Can/how can this accomplished?
#define HTTP_REQUEST_RETURN_ERROR(error) *errCode = error;
#ifdef DEBUG
LeaveCriticalSection(&debugOutputLock);
#endif
return NULL
Thanks in advance,
Jori.
You can also, of course, define the macro twice, with different definitions:
#if defined DEBUG
#define HTTP_REQUEST_RETURN_ERROR(error) do { *errCode = error;\
LeaveCriticalSection(&debugOutputLock);\
return NULL;\
} while(0)
#else
#define HTTP_REQUEST_RETURN_ERROR(error) do { *errCode = error;\
return NULL;\
} while(0)
#endif
That makes sure to avoid the (trivially optimizable) run-time if that xdazz used. It also wraps the macro bodies in the typical do ... while, to make it look like a statement.
UPDATE: To clarify, multi-statement macros in C are often wrapped (in the macro definition) in a do ... while(0) loop, since that makes the entire text into a single statement. This lets the usage of the macro work well with scopes and semicolons.
For instance, consider this:
if(httpRequestFailed())
HTTP_REQUEST_RETURN_ERROR(404);
else
processResults();
Without the do ... while(0), the above would be a syntax error since there would be multiple statements between the if and the else. Just adding braces to the macro expansion isn't very clean, since the desirable statement-like usage like the above would result in expansion of
if(httpRequestFailed())
{ ... /* code omitted */ };
which is not very clean, braces following a code scope are not typically followed by a semicolon.
You cannot nest preprocessor directives in a #define.
Define DEBUG and then use the normal if statement.
#define DEBUG 0
#define HTTP_REQUEST_RETURN_ERROR(error) *errCode = error;
if (DEBUG) LeaveCriticalSection(&debugOutputLock);
return NULL
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.