Return with Macro C programming - c

This code is always returning -1 even when the fopen() function has executed successfully. Is there something I am ignoring.
void nullCheck(FILE* checkVar) {
if(checkVar==NULL) {
#define _NULL_ERROR
}
}
int readFile(char* _name, char* storeArray) {
FILE* fp;
fp=fopen(_name,READ_ONLY_MODE);
nullCheck(fp);
#ifndef _NULL_ERROR
char c=0;
while((c=getc(fp))!=EOF) {
*(storeArray+i)=c;
i+=1;
}
#endif
#ifdef _NULL_ERROR
#undef _NULL_ERROR
return -1;
#endif
return 1;
}
Thanks!

Oy va voy! Macros are defined and undefined when your code is compiled, not when it runs! They are not affected by control flow statements like "if" and "then" -- they are all processed before compilation of those statements even begins!

You need to re-read the documentation on the C Preprocessor. The #define _NULL_ERROR doesn't get executed when nullCheck is called, it gets interpeted when the preprocessor processes the file before it is compiled. So you are always setting _NULL_ERROR and so you will always return -1.

#define is a preprocessor command, which means it's not calculated / processed in the function nullCheck() but before the compiling of the code. so _NULL_ERROR is always defined and therefore the condition
#ifdef _NULL_ERROR
#undef _NULL_ERROR
return -1;
#endif
will always cause the pre-compiler to add the return -1; to your code.

This is what your code looks like to the compiler, after the preprocessor runs:
void nullCheck(FILE* checkVar) {
if(checkVar==NULL) {
}
}
int readFile(char* _name, char* storeArray) {
FILE* fp;
fp=fopen(_name,READ_ONLY_MODE);
nullCheck(fp);
return -1;
return 1;
}
As has been stated above, the preprocessor deals with macros before the compiler runs.

#define, #ifdef, and friends don't work like you think they do. They're preprocessor directives that affect your code even before the compiler sees it. Get your compiler to show you the preprocessed source before it compiles (-E or -save_temps in gcc and clang) and you'll immediately see what's going on.

Related

C Preprocessor, jumping out of #ifdef

I am currently learning C and I came across this question I can't find an answer to.
Can I jump out of a #ifdef without going through the #endif?
For example can I do this:
char getOS( void ) {
/* Returns the user Operating System
*/
#ifdef _WIN32
return 'w';
#elif TARGET_OS_MAC
return 'm';
#elif __linux__
return 'l';
#else
raiseError( "You cannot play on this OS", true );
#endif
}
I believe you are misunderstanding the preprocessor a bit. Remember, the preprocessor runs before the compiler. So this function is going to look like one of the following when it gets to the compiler:
char getOS( void ) {
return 'w';
}
char getOS( void ) {
return 'm';
}
char getOS( void ) {
return 'l';
}
char getOS( void ) {
raiseError( "You cannot play on this OS", true );
}
... and these are all valid. Well I don't know what raiseError does, but if it isn't a macro that returns or exits, you will want to add an extra return to the end of the function for the #else branch.
The point is, none of that #if, #elif, etc is going to the compiler anyway, so you are never "jumping out". If you want to see for yourself, you can add a compiler option to only do preprocessing (and no compiling). I know for gcc, that option is -E.
If by "jump out of", you mean cause the compiler to give an error, you can do that with the #error directive.
#ifdef _WIN32
return 'w';
#elif TARGET_OS_MAC
return 'm';
#elif __linux__
return 'l';
#else
#error "You cannot play on this OS"
#endif
You seem to be confusing preprocessor with runtime behavior: they are not the same.
The preprocessor runs before the actual compiler (at least conceptually; in practice they can very well be the same program of course). It affects the source that the compiler then sees.
You cannot "go through" the #endif, it's not there when the program runs. You will either have a return, or a call to raiseError().

How to use a global variable in #if conditional check?

#define TEST
int i = 1;
int main(int argc, char const *argv[]) {
#if (defined(TEST) && i)
printf("it is printed");
#endif
return 0;
}
Do I have to create another macro for i?
If you want the output if and only if both the macro and the condition on the global variable are true then do like this:
#if (defined(TEST))
if (i)
{ printf("it is printed");
}
#endif
Reason (agreeing with comment by Barmar):
Preprocessor directives are evaluated at compile time, variables are not available at that time.
As in the comments, macro definitions are expanded during the preprocessing stage, before the actual C code compilation.
But why this code compiles and what will be the result of it.
#if (defined(TEST) && i)
preprocessor tests for macro definition TEST. As it was defined, the result of this check is true
now the preprocessor is checking if macro definition (not the C variable!) i exists. As it does not, the whole expression in the #if is evaluated to false.
Generally :
#if a
checks if macro definition a exists and then if its value is != 0,

Stripping specific functions on compile time

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.

expected a ")" in IAR IDE

I got the error Error[Pe018]: expected a ")" at CPU_state == cpuStateOff.
When I change cpuStateOff to 0 it's OK. I don't know why.
In my PERIPHERAL_APP.h:
#ifndef __PERIPHERAL_APP_H
#define __PERIPHERAL_APP_H
// CPU state
#define CPU_STATE_OFF 0;
#define CPU_STATE_ON 1;
#endif
In my main.c:
#include "PERIPHERAL_APP.h"
void main( void )
{
initMSP430();
_EINT();
for (;;)
{
if (cpuState == CPU_STATE_OFF ) // The error is hear
{
__bis_SR_register(LPM3_bits);
}
else
{
__bis_SR_register(LPM0_bits);
}
}
}
Preprocessor macros are not C statements, and therefore doesn't need a statement terminator like ;.
What happens is that when the preprocessor replaces the macro cpuStateOff it uses the whole body of the macro, i.e. 0; which results in code like
if (CPU_state == 0; ) // Code after macro replacement
Most compilers and environments have options to stop after preprocessing, if you use it you can see exactly what code the compiler "proper" will see.

C puzzle: how will you print something on console?

/*you cannot change anything from here below*/
main()
{
exit(0);
}
/*you cannot change anything from here up*/
This was asked during an interview.
I was told to print something on console.
anybody?
Really surprised that nobody posted this yet:
#include <stdio.h>
#if 0
/*you cannot change anything from here below*/
main()
{
exit(0);
}
/*you cannot change anything from here up*/
#endif
int main()
{
printf("Hello, World!");
return 0;
}
Prints at runtime and no undefined behavior whatsoever.
weird question...
int main(void)
{
printf("hello");
return 0;
}
#define main int lol
/*you cannot change anything from here below*/
main()
{
exit(0);
}
/*you cannot change anything from here up*/
#include <stdio.h>
#define exit(c) return puts("foobar"),0
over main
One implementation defined way would be to use the pragma directives to print during compilation.
#pragma message "Compiling " __FILE__ "..."
Or, you could do this with some macros and a printf (but not without introducing UB in some aspect or the other) at runtime.
#define exit(x) printf("Hello, world!")
int main() {
exit(0);
return 0; /* if pre-C99 */
}
#include <stdio.h>
#pragma message("Some foobar")
#error This is an error message
int main()
{
exit(0);
}
I think the interviewer wanted to know if you're aware of the #error directive ... just my 2 cents.
Most answers involve the #define c-preprocessor instruction to change what the program means. Most compilers also support something like
#pragma startup foo()
details depend on the compiler vendor. You can make code run BEFORE main(*) is called that way.
#define exit(x) (printf("Bye"))
int main(int argc,char* argv)
{
exit(0);
getchar();
return 0;
}
Solution 1.
This works without any preprocessor directives in cl and gcc, although I've not tested to make sure I'm not using any extensions:
#include <stdio.h>
static void exit() {
printf("Hello world");
}
/*you cannot change anything from here below*/
main()
{
exit(0);
}
/*you cannot change anything from here up*/
I think it's valid but I can't remember if masking a standard library function is allowed or not.
Solution 2
As several other answers have specified, you can use preprocessor directives, eg:
#define main or exit to be something that calls ifdef
use #if 0 to prevent the existing code being compiled
using #pragma message or #error to print a message at compile time
using #pragma startup to use a different function as main or to run start-up code before main.
Solution 3
If your compiler supports any C++ features in addition to C, there are many answers:
Declare a class with a constructor and a static variable of that type
Put the existing "main" function into a separate namespace (or class definition) and write a different global main
Solution 4
I also looked for any way of forcing a run-time error (stack overflow, out of memory, null dereference, tc), which would normally cause the program to print something, but couldn't find any way that didn't involve running extra code, in which case the extra code might as well be printf.
If you interpreted the question to mean you could not or were not allowed to edit the file by commenting out /* */ or using #ifdef _COMMENT_ME_OUT__ #endif respectively above and below the section you are not allowed to edit and then introducing a new main, then you should give an answer of using another .c file.
If you cannot find a workaround to edit that file, then use a different c file.

Resources