|
|
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
|
|
|
|
|
Presuming that I understand what you are saying.
Member 14968771 wrote: Some objects require knowledge / access of / to previously configured objects
That is basically an incorrect way to think of that unless you stated it incorrectly.
You have class A1 which can have an instance a1. Now a1 not A1 is the only thing that is 'configured'.
Then there is class B1 which has instance b1. And instance b1 needs access to a1. Note that b1 does NOT have access to the configuration for a1. It should not even know that a1 is 'configured'.
Conversely if b1 needs access to the same configuration information as a1 then the configuration information should not be limited to a1 but should be generic.
As an example if you have UI objects that represent a Box and a Button and both use a 'configured' color X then you would call that X something like 'outline.color.border'. You would not call it 'Box.color.border'
Now AFTER you figure out the hierarchy of the configuration data then you figure out the best way to manage it.
Generally you would have a parallel set of configuration objects which in some way are related to each other and which expose the loaded configuration data.
C#, as one example, has a dynamic class structure which supports creating from configuration files. But the same thing can be achieved (and perhaps is easier to understand) just by have one class with a method that takes a name and returns a value.
But regardless the configuration object (or objects) is entirely independent from the classes that use the configuration.
As a reminder do not forget about error handling and default values. If the configuration file is not found or a configuration value is missing (because it is misspelled) then what do you want the application (and objects) to do.
|
|
|
|
|
Message Closed
modified 15-May-23 19:06pm.
|
|
|
|
|
No that doesn't help at all. Making it as simple as I can...
There is a set (one or more) objects that use the configuration.
There is another set (one or more) objects that manage the configuration (lets say read it from a file.)
The two sets must not be the same.
|
|
|
|
|
Message Closed
modified 15-May-23 19:06pm.
|
|
|
|