|
This article can probably explain it a lot better than I can. In particular I did not know that the argument before the ellipses must not be something that is eligible for default parameter promotion (e.g a float, which gets promoted to double).
Modern C++ and Variadic Functions: How to Shoot Yourself in the Foot and How to Avoid It
You should take note of the discussion of how the variadic function determines how many arguments it has.
I also have an idea that stdargs may not be the preferred way to write a variadic function in C++ any longer. There's a tickle in the back of my brain that perhaps variadic templates are a better way to go. If you're interested in that, check out Jason Turners C++ weekly episodes on You Tube: C++ Weekly - Ep 6 Intro To Variadic Templates - YouTube
Keep Calm and Carry On
|
|
|
|
|
It dpends om what type the extra parameters are. If they are all the same (e.g. all ints, chars etc.) then you are better using an array or a C++ container. But if you are passing a variable number of varying types then you need some way of identifying which type each parameter is. In the C library printf/scanf functions this is done with the format string, where each control item in the string tells the function what type to expect for the corresponding variable.
|
|
|
|
|
Besides the other answers you might want to ask how many of these would be reasonable in the next 5 years of using this method.
So if you start with 2 now and there are 4 in 5 years ok.
But if you start with 2 now and in three months there are 20 then that is a problem. In that case a collection of some sort is better.
|
|
|
|
|
" in three months there are 20"
Nah, they're on to the next project.... who cares about code maintenance?
Charlie Gilley
“They who can give up essential liberty to obtain a little temporary safety deserve neither liberty nor safety.” BF, 1759
Has never been more appropriate.
|
|
|
|
|
|
It still requires enforcing correct usage which can only occur via discipline and/or careful code reviews.
And if you are doing that then you shouldn't have a problem in the first place. More careful designs can also reduce the problem.
|
|
|
|
|
My thoughts exactly. Seems more trouble than it's worth.
Mircea
|
|
|
|
|
Message Closed
modified 15-May-23 19:06pm.
|
|
|
|
|
It's not wrong. Empty statement is a valid C/C++ statement. You can try:
;;;;
Also, a very popular beginner mistake is to add a spurious semicolon at the end of a while and wonder why the while "body" is not repeated:
while (i>0); {
}
Mircea
modified 1-Mar-23 14:07pm.
|
|
|
|
|
|
Aren’t we all beginners constantly trying to learn new things? Do you think I saw that error in a book?
Mircea
|
|
|
|
|
To add to what Mircea has said, you may even include empty blocks e.g.
int main()
{
{}
std::cout << "Hello World!\n";
{}
}
compiles without complaint.
While that seems rather silly, source code like that might be generated when a pre-processor #define is expanded or perhaps if you have some sort of code generator as part of the build process. e.g. something like Oracle Pro*C, or Postgresql ecpg.
Keep Calm and Carry On
|
|
|
|
|
Message Closed
modified 15-May-23 19:06pm.
|
|
|
|
|
It's because #ifdef is a preprocessor statement and the the preprocessor requires the #ifdef and the #endif to be on separate lines. What you could do is use Find/Replace to convert all qDebug calls to Debug (or some other unique name), and then add something like the following at the top of you source, or in a common header:
#ifdef DEBUG
#define Debug qDebug
#else
#define Debug
#endif
|
|
|
|
|
Copy the following in a file called script.awk
/qDebug/ {
print "#ifdef DEBUG"
print $0
print "#endif"
}
!/qDebug/
Then a command like
awk -f script.awk source.cpp >new_source.cpp would put a pair of #ifdef/#endif on any line containing qDebug. Obviously replace source.cpp with your source file.
Translated into English, the script says: if line contains the string qDebug , print a line with #ifdef DEBUG, then print the line in question, then print a line with #endif. If line doesn't contain the string qDebug, just print it. The resulting output is put in file new_source.cpp
Good luck!
Mircea
|
|
|
|
|
If you can get Notepad++ working on Linux through Wine, as per this page, you can record a script in it to do the job. Don't know how difficult it will be to do across multiple files, as far as opening them individually goes, but the script can be assigned a keyboard shortcut to make it easier. You can also use extended characters to search and replace every occurrence without having to trigger the macro for each instance in the file.
|
|
|
|
|
Message Closed
modified 15-May-23 19:06pm.
|
|
|
|
|
Create your own Debug class to do it, and change all the qDebug calls to call your class. Then inside your class you can pass the text to qDebug itself, and to your textbox.
|
|
|
|
|
That is C++ , not C .
I show you how it could be handled in a similar scenario:
#include <iostream>
#include <sstream>
using namespace std;
#define STD_DEBUG
#ifdef STD_DEBUG
#define DBG(txt) cerr << txt
#else
#define DBG(txt) \
do { \
ostringstream os; \
os << txt; \
string s = os.str(); \
cout << "The debug string: " << s; \
} while (0)
#endif
int main()
{
DBG("foobar = " << 42 << "\n");
}
"In testa che avete, Signor di Ceprano?"
-- Rigoletto
|
|
|
|
|
Message Closed
modified 15-May-23 19:06pm.
|
|
|
|
|
I think you'll have to explain in more detail what you want to accomplish.
Makefiles and include files are not directly related. Makefiles are "recipes" used to compile and link a binary. You write something like:
module1.o : module1.cpp inc1.h inc2.h
gcc $(CFLAGS) -o module1.o module1.cpp That would tell make that module1.o object file needs to be recompiled every time any of module1.cpp or inc1.h or inc2.h files changes and what is the command to compile it.
Mircea
|
|
|
|
|
You can groupt include statements into a single header file which is then included in every module that requires them. But you should avoid including headers that are not required as that just adds to compilation time. And if you are building for Windows with Visual Studio you can use the "Precompiled Headers" option to make it faster. I do not know whether g++ has a similar option.
As mentioned elsewhere, include statements have nothing to do with make files.
modified 15-Feb-23 5:18am.
|
|
|
|
|
g++ will create pre-compiled headers quite simply: g++ foo.hpp creates a foo.hpp.gch, and the compiler will search for a .gch file when processing a #include directive. If necessary, you can include -x c++-header flags to indicate to the compiler that the named sources are to be treated as header files rather than program source code. Also note that some compiler flags need to match for both PCH and source code. More details here: Precompiled Headers (Using the GNU Compiler Collection (GCC))
Keep Calm and Carry On
|
|
|
|
|
Message Closed
modified 15-May-23 19:06pm.
|
|
|
|
|
I'd say it doesn't matter. There are pros and cons to each solution. If you make it part of the main object you have fewer global/high-level objects but every time you access the configuration you go through the main object. This means at least more typing. If you make it a separate (global) object, the opposite is true.
My own take: some years ago I was going with the config as part of the main object for reasons of "code purity". These days I go with a separate object for pragmatic reasons.
Mircea
|
|
|
|