Create an account

Very important

  • To access the important data of the forums, you must be active in each forum and especially in the leaks and database leaks section, send data and after sending the data and activity, data and important content will be opened and visible for you.
  • You will only see chat messages from people who are at or below your level.
  • More than 500,000 database leaks and millions of account leaks are waiting for you, so access and view with more activity.
  • Many important data are inactive and inaccessible for you, so open them with activity. (This will be done automatically)


Thread Rating:
  • 797 Vote(s) - 3.47 Average
  • 1
  • 2
  • 3
  • 4
  • 5
#if vs #ifndef vs #ifdef

#1
My problem is first of all, understanding `#ifndef` and `#ifdef`. I also want to understand the difference between `#if`, `#ifndef` , and `#ifdef`. I understand that `#if` is basically an if statement. For example:

#include<iostream>
#define LINUX_GRAPHICS 011x101

int main(){
long Compare = LINUX_GRAPHICS;
#if Compare == LINUX_GRAPHICS
std::cout << "True" << std::endl;
#endif
}


But the others, although I read about them I can't comprehend. They also seem like very similar terms, but I doubt they work similarly. Help would be greatly appreciated.
Reply

#2
`#if` is preprocessor `if`. It can only deal with with preprocessor stuff which is basically preprocessor macros (which are either function like or constant-like) and C tokens with some simple integer-literal arithmetic.

`#ifdef SOMETHING` is the same as `#if defined(SOMETHING)` and
`#ifndef SOMETHING` is the same as `#if !defined(SOMETHING)`. `defined` is a special preprocessor operator that allows you to test whether SOMETHING is a defined macro. These are basically shortcuts for the most common uses or preprocessor conditionals -- testing whether some macros are defined or not.

You can find a detailed manual (~80 pages) on the gcc preprocessor at

[To see links please register here]

.
Reply

#3
Well the preprocessors #ifdef and #ifndef mean the followind: In your example you used #define to set a constant variable named LINUX_GRAPHICS to be equal to 011x101. So later in your program you migth want to check if this variable is defined. Then you use #ifdef, when you want to check if this variable is defined and #ifndef if not. I wish I helped you.
Reply

#4
Basicaly, preprocessor does text substitution. Then the compiler compiles program into machine code. And then CPU executes machine instructions. This means you can't use preprocessor `#if` instead of operator `if`: one does text substitution, while second generates branching code for CPU.

So preprocessor directives such as `#if`, `#ifdef`, `#ifndef` serve for "semi-automatic mode" of generating (a little) different programs based on some "meta-input". Actually you can always do these substitutions yourself and get working C/C++ program without any preprocessor directives. Also compilers often have a command-line switch which outputs just preprocessed program, i.e. without any `#if` directives. Try to play with it, and you should get what these directives do.

`#ifdef XXX` is just the same as `#if defined(XXX)` where `defined(XXX)` is builtin preprocessor-only function which is true when identifier XXX is defined in program text by another preprocessor directive `#define`. And `#ifndef XXX` is just `#if !defined(XXX)`.
Reply

#5
`#if` doesn't have any notion about `Compare` or the value it contains, so it probably doesn't do what you intend.

Remember the preprocessor does plain text replacement.

The statement will expand as seen from `#if` as

#if Compare == 011x101

and being expanded as

#if 0 == 011x101


which certainly won't yield `true` at the preprocessing stage.

----------------------------------------------

The `#ifdef` and `#ifndef` directives check if a preprocessor symbol was `#define`'d at all, either using that (<--) preprocessor directive, or your compilers preprocessor option (most commonly `-D<preprocessor-symbol>`).
These don't care if the preprocessor symbol carries an empty value or something. A simple

#define MY_CONDITION

or

-DMY_CONDITION

is enough to satisfy

#ifdef MY_CONDITION

to expand the text coming afterwards (or hide it with `#ifndef`).

----------------------------------

The `Compare` declaration isn't a preprocessor symbol and can't be used reasonably with `#ifdef` or `#ifndef` either.
Reply

#6
Macros are expanded by the preprocessor who doesn't know anything about values of variables during runtime. It is only about textual replacement (or comparing symbols known to the preprocessor). Your line

#if Compare == LINUX_GRAPHICS

will expand to

#if Compare == 011x101

and as "Compare" is different from "011x101", it evaluates to false. Actually I am not even 100% sure about that, but the point is: you are mixing preprocessor directives with variables that are evaluated at runtime. That is non-sense. Preprocessor directives are not there to replace C++ statements.

For most traditional use cases of macros there are better way nowadays. If you don't really need to use macros, it is better not to use them. It makes it extremely hard to read the code (eg. I don't understand how that macros in your code work and unless I really need it honestly I don't want to know :P) and there are other problems with macros that can lead to very hard to find bugs in your program. Before using macros I would advice you to first consider if there isn't a more natural C++ way of achieving the same.

PS:

#ifdef SYMBOL
ifdef = "if defined"
this part of the code is excluded before the compiler even sees it
if SYMBOL is not defined (via #define)
#endif

#ifndef SYMBOL
ifndef = "if not defined"
this part of the code is excluded before the compiler even sees it
if SYMBOL is defined (via #define)
#endif

I wrote "excluded" on purpose to emphasize the bad impact it has on readability of your code. If you overuse `#ifdef` or `#ifndef` inside normal blocks of code, it will be extremely hard to read.
Reply



Forum Jump:


Users browsing this thread:
1 Guest(s)

©0Day  2016 - 2023 | All Rights Reserved.  Made with    for the community. Connected through