I have a question. I have a randomnumber function that I want to be available to all my classes.
In main,
I have the function
int RandomRange(int min, int max)
{
int newValue = (rand() % max) + min;
if ( newValue > max )
newValue = max;
if ( newValue < min )
newValue = min;
return newValue;
}
But I want my classes to be able to use this function. How do I go about something like that?
Create a header:
#ifndef RANDOM_RANGE_H_INLCUDED_
#define RANDOM_RANGE_H_INLCUDED_
int RandomRange(int, int);
#endif
Then include that header in any file that needs to use the function.
When you have time, you might want to write a better implementation of the function.
Declare it as a free-standing function in a header file, and then #include it from everywhere?
The answers saying "put just a declaration in a header file" are right, but it's also worth knowing that you can avoid a separate source file for the definition, and linking the corresponding .o file, by putting this this in a header file:
inline int RandomRange(int min, int max)
{
int newValue = (rand() % max) + min;
// etc...
}
This is simpler, but means that every source file that includes the file will have to process the full definition when it's compiled, and also that every source file that includes this file will have to process <cstdlib>, which this file needs to include in order to call rand().
For such a small function and for a header as basic as <cstdlib>, it's premature optimization to worry about the effects of that on compilation time for a full build, although it will noticeably affect partial builds when this header file is changed. There are also some issues of functionality, though - if you do this then:
(a) object files that used this header file and are linked together must use identical definitions of RandomRange, so a change to the contents of the function body breaks link-compatibility. And that's identical after pre-processing - there are no macros used in this example so it's the same either way, but it's possible to make mistakes here.
(b) you can't replace the definition of RandomRange just by linking a different object file containing a different definition (for debugging, testing, or link-time application configurability).
For small functions and small projects, these drawbacks aren't normally a concern. For large functions and large projects, normally at least some of them are, which is why the standard safe thing is to have separate declarations and definitions.
Related
Is it possible to code a library with a parameter that will be defined by the user at compile time without modifying the library?
Library:
test.h
#ifndef TEST_H
#define TEST_H
#define MAX_NB USER_DEF
void myFunc();
#endif
test.cpp
#include "test.h"
int arr[MAX_NB] = {0};
void myFunc() {
for (int i = 0: i < MAX_NB; i++ ) {
// DO SOMETHING
}
}
And the main code:
#define USER_DEF 5
#include "test.h"
void main() {
while (1) {
myFunc();
}
}
I suppose I am getting an error (USER_DEF not declared in this scope) because USER_DEF is not defined in the translation unit containing test.h and test.c, but I hope there is a way to do it, but I can't find it.
My goal is to have an array with a user-defined size (code modified).
The answer is that it doesn't make sense to use variable-sized arrays for a very restricted 8-bit system with very limited RAM.
Instead you should have a fixed size array of n bytes. Let the user pick a number, then ensure that it is less or equal to n. Then keep track of the used size with a plain integer variable. You must always reserve memory for the worst case.
The array must have static storage duration, since it will be too large to be allocated on the stack.
I'd usually go and suggest to check out the templates, although, you can create user-defined variables, they are called function parameters. Please take a look
To sum it up, this is not what you call user-defined variable, because this is defined by the programmer, not by the user of the program. This is called a constant, whatsoever. If you want to create a compile-time constant, defined by you, you can take a look at constexpr.
Also, let me explain to you why this doesn't work correctly. You guessed correctly, it's because it is not defined into the header file, but why? Because headers come first and then comes the main file. The header searches for the defined constant and fails to find it, and that is the reason why you get the USER_DEF not declared in this scope.
I came across a c++ code where a function was defined in the header section of the file as follows
#define APPEND_VALUE(X, Y, I)\
{\
int idx = (Y*100+X);\
int idxn = idx + ValueCount[idx];\
TempVector[idxn] = I;\
CountVector[idx] += 1;\
}
(Note that this is not all the code and TempVector and CountVector was defined elsewhere)
Later in the code APPEND_VALUE was used like any other function. I was wondering what is the difference between the above (#define APPEND_VALUE) code and the below code
void APPEND_VALUE(int X, int Y, int I)
{
int idx = (Y*100+X);
int idxn = idx + ValueCount[idx];
TempVector[idxn] = I;
CountVector[idx] += 1;
}
What is the advantage of using one over the other? also is there a technical name for defining a function as show in the first code(the one using #define).
#define is part of something called the "preprocessor." Essentially, this is the code that is processed before the C document is compiled. Most of the preprocessor code is in a file with a ".h" extension (which is why you may have seen that when importing libraries).
The preprocessor language is primitive. For example, if it performs a "textual substitution [with] missing parentheses", the result of the preprocessor function may not be what you intended it to return (credit: #Deduplicator). Take a look at this post for an example: #define Square(x) (x*(x)). For this reason, and many others, I would prefer coding it in the regular C language when possible (just note there are many cases where the preprocessor may be faster and more helpful). Hope this helps!
header.h
int m_linkinfo;
m_linkinfo = 1;
main.cpp
#include "header.h"
int main()
{
return 0;
}
Failed, with many errors. But if I commented the line m_linkinfo = 1;, everything is OK. Why? Cannot I assign values to a variable in header file? But If I changed the header file to the only one line: int m_linkinfo = 1;, The program is compiled successfully! Why? Is it different from the two lines of code above?
No, you can't. That's a piece of code so it needs to exist inside a function of some sort, such as:
int main () {
m_linkinfo = 1;
return 0;
}
You can, as you have seen, initialise it with:
int m_linkinfo = 1;
however, since that's allowed by the standard.
Keep in mind that it's often risky to define things in header files. By define, I mean statements that create things as opposed to those that simply notify the compiler than things exist (declaring).
That's because including the header in two different translation units can result in two copies of a thing with the same name and, if you subsequently try to link them together, you'll run into trouble.
The best way to solve that is to declare things in header files, such as:
extern int m_linkinfo;
and define them in a non-header (eg, CPP) file:
int m_linkinfo = 1;
That way, every translation unit that includes the header knows about m_linkinfo but only the CPP file creates it.
C doesn't allow code outside of functions. In your example:
int m_linkinfo;
m_linkinfo = 1;
The second line is illegal, since it isn't in a function.
Outside of functions you can only declare or define variables and functions (or give directions to the preprocessor).
However, you are allowed to initalise a variable when you define it, so you can do this:
int m_linkinfo = 1;
which is perfectly legal.
Assignment is a statement. Statements are only allowed in functions. The line in the header file is not in a function. Therefore it cannot work.
I'm trying (or rather struggling) to create a little Blackjack game. After some JavaScript courses and a few little projects I decided to switch to C++ and found it a little bit problematic, here is my code:
http://pastebin.com/raw.php?i=4MgC1VcD
For many of you this code can be just crappy, but it makes me really happy to code, even if it doesn't work as I wanted it to :)
This is what i get:
http://i.stack.imgur.com/HpyvC.png
You need to define the method random as inline.
inline int random(int nMin, int nMax)
{
return rand() % (nMax - nMin + 1) + nMin;
}
Otherwise, each translation unit that includes the header will generate code for it.
Either this, or just declare it in the header and define it in an implementation file.
Also, declare globals as extern:
extern std::string sSuits[];
extern std::string sRanks[];
and initialize them in an implementation file.
I've come up with a solution to a problem but I'm not sure if it'll always work or just on my compiler. First, the problem: I've noticed in a number of situations it's desirable to have a template class that gets re-instantiated each time it's used even when given the same types (say your template class has static members that are initialized to function calls that have some important side effect -- and you want this side effect to be done every time the template is used). The easy way to do this is to give your template an extra integer parameter:
template<class T, class U, int uniqueify>
class foo
{
...
}
But now you have to manually make sure that every time you use foo you pass it a different value for uniqueify. The naive solution is to use __LINE__ like this:
#define MY_MACRO_IMPL(line) foo<line>
#define MY_MACRO MY_MACRO_IMPL(__LINE__)
This solution has an issue though -- __LINE__ gets reset for each translation unit. So if two translation units use the template on the same line, the template only gets instantiated once. That may seem unlikely, but imagine how difficult to debug the compiler error it would be if it did happen. Similarly you could try using __DATE__ as a parameter somehow, but that only has seconds precision and it's the time when compiling started, not when it reaches that line, so if you're using a parallel version of make it's rather plausible to have two translation units with the same __DATE__.
Another solution is that some compilers have a special non-standard macro, __COUNTER__ that starts at 0 and increments every time you use it. But it suffers from the same problem -- it gets reset for each invocation of the preprocessor, so it gets reset each translation unit.
Yet another solution, is to use __FILE__ and __LINE__ together:
#define MY_MACRO_IMPL(file, line) foo<T, U, file, line>
#define MY_MACRO MY_MACRO_IMPL(T, U, __FILE__, __LINE__)
But you can't pass char literals as template parameters according to the standard because they don't have external linkage.
Even if this did work, whether __FILE__ contains the absolute path to the file or just the name of the file itself isn't defined in the standard, so if you had two identical named files in different folders, this could still break. So here is my solution:
#ifndef toast_unique_id_hpp_INCLUDED
#define toast_unique_id_hpp_INCLUDED
namespace {
namespace toast {
namespace detail {
template<int i>
struct translation_unit_unique {
static int globally_unique_var;
};
template<int i>
int translation_unit_unique<i>::globally_unique_var;
}
}
}
#define TOAST_UNIQUE_ID_IMPL(line) &toast::detail::translation_unit_unique<line>::globally_unique_var
#define TOAST_UNIQUE_ID TOAST_UNIQUE_ID_IMPL(__LINE__)
#endif
Why this works isn't really clear without a usage example, but first an overview. The key insight I had was to see that every time you make a global variable or a static member variable, you're creating a program wide unique number in the form of the address of that variable. So this gives us a unique number that's available at compile time. __LINE__ makes sure we won't get clashes within the same translation unit, and the outer anonymous namespace makes sure the variables are different instances (and thus get differing addresses) across translation units.
Example usage:
template<int* unique_id>
struct special_var
{
static int value;
}
template<int* unique_id>
int special_var<unique_id>::value = someSideEffect();
#define MY_MACRO_IMPL(unique_id) special_var<unique_id>
#define MY_MACRO MY_MACRO_IMPL(TOAST_UNIQUE_ID)
And foo.cpp becomes:
#include <toast/unique_id.hpp>
...
typedef MY_MACRO unique_var;
typedef MY_MACRO unique_var2;
unique_var::value = 3;
unique_var2::value = 4;
std::cout << unique_var::value << unique_var2::value;
Despite being the same template, and the user providing no differentiating parameters, unique_var and unique_var2 are distinct.
I'm mostly worried about the address in of the variable in the anonymous namespace actually being available at compile time. Technically, an anonymous namespace is like declaring internal linkage, and template parameters can't have internal linkage. But the way the standard says to treat anonymous namespaces is just like the variable was declared as part of a namespace with a program-wide unique name, which means that technically it does have external linkage, even though we don't usually think of it as such. So I think the standard is on my side, but I'm not sure.
I don't know if I've done the best job of explaining why this would be useful, but for the sake of this discussion, it is, I swear ;)
This technique is not safe in general, for two reasons.
__LINE__ can be equal on two different lines in the same translation unit, either through #line directives, or (more commonly) through use on the same line number in multiple header files.
You will have ODR violations if you use TOAST_UNIQUE_ID or anything derived from it within in inline function or template definition in a header file.
That said, if you never use this in header files, and don't use #line in your main source file, and only use the macro once per line, it seems safe. (You can remove that last restriction by switching from __LINE__ to __COUNTER__.)
This should be safe - but simpler way would be to just use FILE. Also, an int isn't enough on a 64-bit platform. Use an intptr_t:
template<const char *file, int line>
class unique_value {
static char dummy;
unique_value() { }
public:
static intptr_t value() { return (intptr_t)&dummy; }
};
#define UNIQUE_VALUE (unique_value<__FILE__, __LINE__>::value())
Further, keep in mind that this will break down when used within a macro or template.
Also, templates with static values with side effects are a bad idea - remember that the side effects occur in arbitrary order, before main() is called - and burying initialization side effects in random functions is not very good for maintainability.