Is using #define considered "bad practice"? [duplicate] - c++

This question already has answers here:
static const vs #define
(11 answers)
Closed 4 years ago.
Goal
In the end, I want to know if using #define is bad for your code, and why.
Code
#include <iostream>
using namespace std;
#define favouriteNumber 20;
int main()
{
int number = favouriteNumber;
cout << number;
}

According to Stroustrup it's particularly "bad" for defining constants because the compiler can't check types then.
On the other hand, if one line of macro saves you 20 lines of explicit code, some people will certainly agree that it's useful even if it's inherently unsafe. That's because writing more code usually implies higher probability for mistakes.

Related

std::optional compile passes, but run fails [duplicate]

This question already has answers here:
Assign a nullptr to a std::string is safe?
(4 answers)
Why is assignment of 0 or nullptr to std::string allowed, even when it results in a straight forward runtime exception?
(2 answers)
Closed 10 months ago.
I've been trying to introduce std::optional into my projects lately, and it's great! But now I'm a bit confused, look at the following code:
#include <iostream>
#include <optional>
#include <string>
using namespace std;
int main()
{
std::optional<string> s = nullptr;
return 0;
}
This code build normally without any warnings! This is bad, because if I accidentally assign nullptr to std::optional in my project, it will cause a panic, but I can't find it at compile time! There may be other ways to catch this error at compile time, but I don't know of them right now. Does anyone have any good ideas?

how come an undeclared variable is outputting a value [duplicate]

This question already has answers here:
Why is "using namespace std;" considered bad practice?
(41 answers)
Closed 5 years ago.
In my function sumofrange I decided to output an undeclared variable just to learn the different compiler errors in C++. To my surprise, time seems to output 1 even though it is not declared anywhere.
#include <iostream>
#include <cmath>
using namespace std;
int sumOfrange( int lower, int upper){
cout<<time<<endl;
return ((( (pow(upper,2)) + upper) - ((pow(lower,2)) + lower)) / 2);
}
int main(){
cout<<sumOfrange(7,100)<<endl;
return 0;
}
You are outputting the address of a std::time function declared in a <ctime> header. You are also using a using namespace std; statement. Why that should be avoided is explained in this SO post. Depending on the compiler and the platform you might get the hexadecimal output similar to (0x)00DC52E0 if using a VC++ compiler on Windows or a number 1 if using a g++ compiler on Linux.

c++ #include macro names must be identifiers [duplicate]

This question already has answers here:
what is the difference between #include<> and #define"" [closed]
(2 answers)
Closed 6 years ago.
I'm making a C++ header file for learning purposes. It's supposed to give me the length of the number (be it an int, float, double etc.) without counting the comma. Here's my code:
#ifndef NUMLEN_H
#define NUMLEN_H
#define <cstring>
int numlen (char numberLengthSample[]) //numlen - lenghth of the number, numberLengthSample - the number you put in.
{
int numberLengthDummy = strlen (numberLengthSample); //a temporary int used in counting the length
int numlenc = strlen (numberLengthSample); //the true length of the number
while (numberLengthDummy>0)
{
if (numberLengthSample[numberLengthDummy-1]=='.'||numberLengthSample[numberLengthDummy-1]==',')
{
numlenc--;
}
numberLengthDummy--;
}
return numlenc;
}
#endif // NUMLEN_H
But it gives me 3 errors:
1) (line 3) macro names must be identifiers
2) (line 7) 'strlen' was not declared in this scope (obviously)
3) (line 5 (when executed from my test .cpp)) initializing argument 1 of 'int numlen(char*)' [-fpermissive]|
I tried to look for an answer, yet with no prevail. Any help would be appreciated :) .
In C++ you have to #include headers instead of #define them:
#ifndef NUMLEN_H
#define NUMLEN_H
#include <cstring>
It's not related to the question, but you should only declare functions inside header file and implement them inside source file.
The problem is because you are using #define instead of #include, it should be:
#include <cstring>

Including windows.h causes an error [duplicate]

This question already has answers here:
How do I deal with the max macro in windows.h colliding with max in std?
(6 answers)
Closed 7 years ago.
This is rather bizarre, I have a class I've been building and currently I have this at the top of my file:
#pragma once
#include <cstdint>
#include <cstring>
#include <string>
#include <limits>
Now I need to add windows.h to the mix but as soon as I do that, I get "Error: expected an identifier" on this line:
inline uint32_t Hash2(std::string &Key) {
return (MurMur3::x86_32(Key.c_str(), Key.size(), 2) % (std::numeric_limits<uint32_t>::max() - 1)) + 1;
}
the red line appears under the ::max if that matters. As for the function itself, its supposed to use murmur3 to get me a hash that isn't 0.
If I remove
std::numeric_limits<uint32_t>::max()
and replace it with the constant 4294967295
then it works fine again.
I don't understand why this is happening. Does anybody have a clue?
Windows.h has a very bad habbit of defining macros in it. In particular, it defines min and max. You need to undef those.

Array defined as "_end[LEN]" causes segmentation fault in C/C++ [duplicate]

This question already has answers here:
What are the rules about using an underscore in a C++ identifier?
(5 answers)
Closed 7 years ago.
I tried to define a global array, named _end, of size ~1000 in C/C++, but I got a segmentation fault even when I simply iterated it. Is the name "_end" very special in C/C++ that causes such problem? Or this can be a very serious bug... (The code is attached below, and it breaks in g++ 4.3.2, 4.5.2, 4.9.2, etc.)
#include <iostream>
using namespace std;
int _end[1111];
int main() {
for (int i=0; i<1111; i++) {
cout << i << endl;
_end[i]++;
}
return 0;
}
You can see the result at https://ideone.com/XAcUeZ.
See here also for the C compiler.
Names which start with an underscore (or two) are reserved for the compiler. This is official C++ standard. Use at own risk.