Can you use scanf() to define a variable set with #define? - c++

If I initialize a variable using #define, can I then set its value using scanf()? i.e. does this work:
#define miscellaneous
printf("What value would you like to use for this example: ");
scanf("%g",&miscellaneous);
If I can't do it this way, is it even possible to set the value of a variable defined this way?

#define miscellaneous means that every time you write miscellaneous, you would like the compiler to replace it with nothing. #define is automated copy-paste and in this case it pastes nothing.
So when you write scanf("%g", &miscellaneous); the macro (the #define) causes it to be changed to scanf("%g", &); which is not valid at all. This is not a variable.

If I can't do it this way, is it even possible to set the value of a variable defined this way?
miscellaneous is not a variable at all. What you have defined is a macro. And no, you cannot set the value of a macro at runtime. Macro processing happens before compilation which happens before the program is run.
P.S. Avoid unnecessary use of macros.

You can not assign value to macro. Using #define directive compiler only in compile time using it, in runtime everything defined using #define directive does not exist.

Related

What is the difference between #define and creating a normal type?

In C/C++, what is the difference between using #define [and #ifndef #endif] to create values, when you can easily do it with an int or std::string [C++] too?
#ifndef MYVAL
#define MYVAL(500)
#endif
//C++
cout << MYVAL << endl;
//C
printf(MYVAL);
//C++
int MYVAL = 500;
cout << MYVAL << endl;
//C
int MYVAL = 500;
printf(MYVAL);
Your assumptions are wrong. #define doesn't create "values", it creates replacement text in your source code. It has basically nothing to do with C or C++ at all.
Before I jump into history, here's a brief understanding of the difference between the two.
Variables are, well, variables. They take up space in the compiled program, and unless you mark them with const (which is a much later development than macros), they're mutable.
Macros, on the other hand, are preprocessed. The compiler never sees the macro. Instead, the macros are handled before compiling. The precompiler goes through the code, finds every macro, and replaces it verbatim with the macro text. This can be very powerful, somewhat useful, and fairly dangerous (since it's modifying code and never does any checking when doing so).
Also, macros can be set on the command line. You can define as many things as you want when you are compiling, and if your code checks for that macro, it can behave differently.
Macros existed long before C++. They have been useful for many things:
You can use them very easily to represent constant expressions. They can save space, because they don't require any variables (though the constant expression still needs to be compiled in somewhere), and they existed before the const specifier, so they were an easy way to maintain constant "variables" - the precompiler would replace all instances of MYVAR with 500.
You can do all sorts of functions with them. I actually never made any myself, because the benefits never seemed to outweigh the risks. Macro functions that aren't carefully constructed can easily break your compile. But I have used some predefined macro functions.
#define macros are still used for many things
include guards (header files usually have a macro defined at the top, and check if it's defined to make sure they don't add it again),
TRUE and FALSE in C,
setting DEBUG mode so that code can behave differently for debugging and release. As one simple example, assertions are functions that behave differently if the DEBUG macro is present. (If it's not present, it returns completely empty code.)
In the limited case where you're simply using a macro to represent a constant expression, you're right - they're no longer needed for that.
The difference is that with the macros (#) the preprocessor does a search and replace on that symbol. There is no type checking on the replace.
When you create a variable, it is typed and the compiler will do type checking where you use it.
C/C++ compilers are often thought of as 2-pass compilers. The first pass is the preprocessor which does search and replace on macros. The second pass is the actual compilation where the declared variables are created.
Macros are often used to create more complex expressions so the code doesn't have to be repeated more than once and so the syntax is more compact. They are useful, but also more dangerous due to their 'blind' search and replace nature. In addition, you can't step into a macro with a debugger so they can be harder to troubleshoot.
Also, macros do not obey any scoping rules. #define MYVAL(500) will replace MYVAL with 500 even if it occurs in functions, global scope, class declarations, etc. so you have to be more careful in that way.
When you #define something, it will be blindly replaced whenever it's found in your code:
#define the_answer 42
/// ...
int the_answer = /* oops! */
There are few important reasons why you shouldn't use #defines. For your questions in particular I would say, #define are plain text replacements and you can't limit the scope of the macro. i.e, you can't specify an access specifier or bind it to a namespace, so once you define the macros you can use them anywhere in the files where the define is included.
With 'const' variables you can have them bound in a scope
These could help : http://www.parashift.com/c++-faq/const-vs-define.html
http://www.parashift.com/c++-faq/preprocessor-is-evil.html
There is a huge difference:
a) #define MYVAL 500
This will create a macro. Each of its occurences in the source code will be replaced by its raw value by the preprocessor. It completely ignores the scope and you cannot change its value
b) int MYVAL = 500;
This is a regular variable that obeys scope rules, i. e. when declared inside a function, it cannot be seen outside it, it can be shadowed within another function, etc...
On the other hand, variables cannot be used in preprocesor conditions (#if, #endif blocks)
One last example:
#define MYVAL 500
int main() {
int MYVAL = 10; // illegal, gets preprocessed as int 500 = 10;
}
Same with variable:
int MYVAL = 500
int main() {
int MYVAL = 10; // legal, MYVAL now references local variable, ::MYVAL is the global variable
}

Avoid macro to be usable from client code

I'm currently working on a header only library and I'd like to be able to use some macros without them being usable from client code. Example:
// library_header1.h
#define MACRO_NUMBER_1(__X__) doSomethingWith(__X__) // etc...
class LibraryClass1
{
// We'll use the macro somewhere in here.
};
Now, if I include library_header1.h i'm able to use MACRO_NUMBER_1. Is there any way I can avoid that?
Others already mentioned #undef but what if you have many macros you need to undefine and you need to use them in many headers? This situation can be dealt with by having a header define and undefine macros and bewteen that include a specified header. For example:
// temp-macros.h
#if defined(OUTER)
# define MACRO x
# include OUTER
# undef MACRO
# undef OUTER
#endif
The idea is to set up OUTER from the header where the macros are neede, include temp-macros.h and use the macros in the second inclusion:
// macro-use.h
#if !defined(OUTER)
# define OUTER "macro-use.h"
# include "temp-macros.h"
#elif !defined(INCLUDED_MACRO_USE)
# define INCLUDED_MACRO_USE
void use(int MACRO) { /*...*/ }
#endif
Of course, this example uses just one trivial macro but if there are more macros and they are more complicated this approach could be useful.
To prevent the library user from accessing the macro - you can put #undef when you know you won't need your macro anymore.
If you want to prevent intellisense/autocompletion from ever seeing your macro, you may try to trick it by skipping it over the macro definition. Usually you can do it as follows:
set up your compilation project (visual solution, makefile, ...) so that you pass an extra "identification" macro. Something like -DIAMCOMPILING
Guard your macro definition with #ifdef IAMCOMPILING ... #endif
your IDE will most likely not recognise IAMCOMPILING and skip over the definition of your macro.
Do note however, that then IDE will get confused when your actually use the macro in the header file and some nonexistent errors will be flagged.
Whilst it won't stop the macro from being noticed by the IDE, if you use a unusual prefix to the macro, it will be less likely to collide with something that the user will want to do, and thus be less offensive. It may not be the ideal solution, but prefixing the macro with CCC or XWX or something else that is unlikely to be used by the normal programmer may help.
(Or, don't use macros is always a solution that works!)

C++ preprocessor ensure globally unique string

I have a Macro function which takes a name and is intended to be called from various namespaces. I want to ensure that this name be unique globally. The define looks something like this:
#define DECLARE_NEW_MYVAR( Name ) static MyVar Name( #Name )
I want this static variable to be namespaced (which is why I expect it to be called from various namespaces) but I also need to ensure that the string being passed to the constructor of MyVar is globally unique. This is because I am going to serialize this value and I need to be able to associate it back correctly.
A few things that I tried without success:
To Force it to be Unique: Based on some information append something to the name to force it to be unique
Use the __COUNTER__ macro: One of the compilers I am targeting does not have this Macro. Also, it seems dangerous to assume that the order in which the Macro is called will be the same
Use the __FILE__ macro: This has the entire filepath which is good to make sure that it is unique, but if compiled from a different place or a different machine, the deserialization would no longer work.
To Check if it is Unique: Leave it up to the caller for it to be globally unique and have the compiler complain if it is not
I was looking for a way to declare something in the global namespace from within a namespace so that I could at least cause a multiply defined symbols if they don't make it unique. I couldn't figure out a way to do this.
Basically I need to come up with a globally unique string to pass to MyVar that I can trust will not change between different compilations and preferably not change between code changes (as long as the specific call hasn't been changed).
Does anyone know how to do this?
You could remove the prefix to the project directory from __FILE__ like this:
#include <cstring>
#include <iostream>
#define COMMON_PATH_PREFIX "/home/user/path/to/project/"
#define UNIQUE_IDENTIFIER() (__FILE__ + std::strlen(COMMON_PATH_PREFIX))
void someFunction(const char *identifier)
{
std::cout << identifier << std::endl;
}
int main()
{
someFunction(UNIQUE_IDENTIFIER());
}
The COMMON_PATH_PREFIX could be #define'd by your build system. If you use CMake for example you could simply use CMAKE_SOURCE_DIRECTORY.
The call to std::strlen() should be optimized out by your compiler, since the string is constant and known at compile time.
Of course this only works if you only want to declare one variable per file. You could also add __LINE__ to the identifier, but then it's much more likely that the identifier changes if you change your code.

Preprocessing Macro

if in the beginning of my file i do
#define dbg_kprintf \
if (x_var) kprintf
I late on do statements using
dbg_kprintf ("blablabla");
My question is that will dbg_kprintf be only defined if xvar is defined somewhere else? If it is not then will dbg_kprintf statements not be used at compile time?
Thanks.
No, that will either compile into a run-time check of the variable, or nothing (if the variable is in fact compile-time constant with a false value and the optimizer feels like eliminating the dead code) or a call always (if it's a compile-time constant with a true value). So, now you know.
The typical way to ensure that debug code is excluded from non-debugging builds is to use a preprocessor symbol to guard the code. Note that it might require you to manage the arguments differently.
No, in that example, x_var has to exist somewhere or it will fail to compile. You are looking for something like
#if (x_var)
#define dbg_kprintf kprintf
#else
#define dbg_kprintf
#endif
In C/C++ Macros can take arguments. It will be defined either way, as it's just a pre-processing directive but the compile will fail if it's not defined. To pass an argument to a macro use this syntax
#define foo(X) ((X))
dbg_kprintf will be used before complie time. The preprocessor will substitute in its place the contents you defined: if (x_var) kprintf. Then it will try to compile your code normally.

C++: How to create enum within a function?

I want to simplify things, by not creating a list of enum separately, but create the enums along the function call which creates the data where i point with those enums.
I tried to make #define which would create another #define, but it didnt work:
int defcounter = 0;
#define make_def(enumname, somedata) \
#define enumname defcounter \
defcounter++; \
func_call(somedata); \
void createstuff(){
make_def(MY_ENUM_NAME, mydata);
make_def(MY_OTHER_ENUMNAME, mydata);
}
void dostuff(){
somefunc_call(MY_ENUM_NAME);
somefunc_call(MY_OTHER_ENUMNAME);
}
But this will create error at the #define enumname:
error C2162: expected macro formal parameter
How can I make this work?
It is impossible to create new types (classes, enums, unions, whatever) at runtime in C++. One of the major features of C++ is that it is statically typed - all types must be known at compile time.
Preprocessor commands (#define, #if, #pragma, #include, ...) cannot appear in macros / defines. The problem is, that the CPP (C-Preprocessor) seperates commands by newlines, while C and C++ are unaware of newlines. In C/C++ you can write everything on one line, for preprocessor commands, you can't.
#define MY_MACRO(name) \
#define name##_macro something_cool \
enum name{ \
.... \
}
// somewhere else
void myfunc(){
MY_MACRO(myfunc_enum);
}
Now, at preprocessing time, those lines all get glued into one big line, thanks to the \ backslash:
#define MY_MACRO(name) #define name##_macro something_cool enum name{....}
Now, how would that macro look at usage?
void myfunc(){
#define name##_macro something_cool enum name{....};
}
Now, the preprocessor has to run over that #define again. But exactly what belongs to the #define, and what doesn't? For the coder it was clear when the macro was written in seperate lines, but now it isn't anymore.
What exactly is your desired output? You need to explain what you think you might get as output from the C preprocessor.
You have scope problems and an attempt to define a macro inside the replacement text of another macro.
Scope
The macro make_def() invokes an undefined function 'func_call'. The createstuff() function uses an undefined variable mydata. And function dostuff() seems to call an undefined function somefunc_call() with an enum that might, perhaps, have been defined inside a separate function.
If an enumeration is defined inside one function, that enumeration is not available to code outside that function, and specifically is not available to either called functions or calling functions. That alone limits the utility of what you seem to be attempting to do. (Yes, the enumeration values might be implicitly converted to int or some similar type, but it is not really the enumeration type that is being used.)
Defining macros in macros
You cannot create a macro that itself contains #define or any other preprocessor directive in its replacement text.
If the outer macro is invoked, the expansion does not interpret the inner #define as being a preprocessor directive, so it almost always ends up as an error, In context the # must be a stringize operator, and the word 'define' after it would have to be the name of an argument to the outer macro to have a chance of working.
// Does not work as intended
#define macro(define, prefix) #define another(name) foo(prefix ## name)
macro(something, other);
Generates:
"something" another(name) foo(othername);
The _Pragma in C99 is a partial exception to the 'a macro expansion cannot contain a preprocessor directive', but it (_Pragma) does not start with #.
Your macro is incorrect, since you cannot use a macro to create another macro, unfortunately, as the toke # has special meaning in the expansion-list: it can either quote a macro argument, or expand another macro. One easy (albeit poorly designed) way you could do this is just to use old c-style #define MY_ENUM_NAME valueas c macro do not respect scope, but this would not be good design. Another possibility is to pass in string arguments and hash on them, but all depends on what you want to do.