How to use autoindent the preprocessor directives
For example in Visual studio all preprocessor directives intended like
this
void test(){
#if _SOME_VAR
std::cout << "test" << std::endl;
#if _SOME_VAR2
std::cout << "test2" << std::endl;
#endif
#endif
}
How can i make code auto indents like this
void test(){
#if _SOME_VAR
std::cout << "test" << std::endl;
#if _SOME_VAR2
std::cout << "test2" << std::endl;
#endif
#endif
}
The solution is
Tools->Options->Text Editor->Indentation->Position of preprocessor
directives
Related
I am working on program that uses a DLL library (LibPlcTag : https://github.com/libplctag/libplctag) and I wanted to add some exception handling to 'my' code. However after finding this was not working, that is the thrown exceptions were not being caught, I managed to distill it all down to the following bit of demonstration code.
So the question is what is going on here ? Why does a call to a DLL function kill C++ try catch ? Is there a way to fix this ?
FYI : I am using Mingw32 C++ with -std=c++11 compiler build flag on Windows 11.
#include <iostream>
#define SHOWERROR 1
#if SHOWERROR
#ifdef __cplusplus
extern "C" {
#endif
__declspec(dllimport) int plc_tag_check_lib_version(int req_major, int req_minor, int req_patch);
#ifdef __cplusplus
}
#endif
#endif
int main(int argc, char *argv[])
{
#if SHOWERROR
std::cout << "Call DLL function" << std::endl;
plc_tag_check_lib_version(0,0,0);
std::cout << "Call Finished" << std::endl;
#else
std::cout << "No DLL Function Call !!" << std::endl;
#endif
try
{
std::cout << "Throw error" << std::endl;
throw "Error";
}
catch( ... )
{
std::cout << "Exception happened" << std::endl;
}
std::cout << "End" << std::endl;
return 0;
}
With SHOWERROR = 0 the exception is caught :
No DLL Function Call !!
Throw error
Exception happened
End
C:\...\test>
But with SHOWERROR = 1 the exception is not caught and the program terminates without printing 'End' :
Call DLL function
Call Finished
Throw error
C:\...\test>
After working on the hunch that my build LibPlcTag was broken in some way I went back to the beginning and instead of using the MinGW32 (5.1.0) that was installed by PlatformIO for 'platform = windows_x86' I installed MSYS2 and the mingw-w64-i686-toolchain.
I then re-built the LibPlcTag library to get a new DLL.
I then used the mingw toolchain above to rebuild the my test app. Now it works and the exception is caught.
The final test code :
#include <iostream>
#include <fstream>
#define SHOWERROR 1
#if SHOWERROR
#ifdef __cplusplus
extern "C" {
#endif
__declspec(dllimport) int plc_tag_check_lib_version(int req_major, int req_minor, int req_patch);
#ifdef __cplusplus
}
#endif
#endif
// void not_called()
// {
// std::cout << "Call DLL function" << std::endl;
// #if SHOWERROR
// plc_tag_check_lib_version(0,0,0);
// #endif
// std::cout << "Call Finished" << std::endl;
// }
int main(int argc, char *argv[])
{
#if SHOWERROR
std::cout << "Call DLL function" << std::endl;
plc_tag_check_lib_version(0,0,0);
std::cout << "Call Finished" << std::endl;
#else
std::cout << "No DLL Function Call !!" << std::endl;
#endif
try
{
std::cout << "Throw error" << std::endl;
throw "Error";
}
catch( ... )
{
std::ofstream debugFile("debug.txt");
debugFile << "Exception happened" << std::endl;
debugFile.close();
std::cout << "Exception happened" << std::endl;
}
std::cout << "End" << std::endl;
return 0;
}
And output :
Call DLL function
Call Finished
Throw error
Exception happened
End
C:\...\test>
Thank you to those that contributed the above thoughtful comments...
Here is the code:
void DBG() { cerr << "]" << endl; }
template<class H, class... T> void DBG(H h, T... t) {
cerr << to_string(h); if (sizeof...(t)) cerr << ", ";
DBG(t...); }
#ifdef _DEBUG
#define dbg(...) cerr << "LINE(" << __LINE__ << ") -> [" << #__VA_ARGS__ << "]: [", DBG(__VA_ARGS__)
#else
#define dbg(...) 0
#endif
Im currently using g++ on vs code on a mac and whenever I run my program using this and for example
I write dbg(10) on main the program does not even run and does not do anything(it outputs nothing).
How can I change this code so it would work on g++ without having to download clang?
Note: I saw some people use #ifdef LOCAL instead of #ifdef _DEBUG but it still doesn't work for me(does not output anything). How do I get #ifdef LOCAL or #ifdef _DEBUG to work on g++?
I have a C++ class which logs messages to a std::ofstream. In the class definition is this code:
#ifdef NDEBUG
#define FOO_LOG(msg) /* calls to log messages are no-op in release mode */
#else
std::ofstream log_stream;
#define FOO_LOG(msg) if (log_stream.is_open()) { log_stream << msg << std::endl; }
#endif
The constructor for that class has several things it checks, and in certain situations will open the log file similar to this:
#ifndef NDEBUG
log_stream.open("output.log");
#endif
Then in the code, it calls the C macro like this:
FOO_LOG("stuff=" << stuff << " in loop counter #" << xyz)
It is convenient that you can pass multiple params to the FOO_LOG() macro. There are obvious limitations, like when logging messages from multiple threads, but this is only used for simple logging in debug builds.
What I want to know is whether there is a different/better way to deal with the msg parameter in C++? Is there a simpler/cleaner way to implement something similar to FOO_LOG() in C++?
Instead of having #ifdef NDEBUG everywhere in your code you can have a #ifdef NDEBUG at the start of the header to define other useful macros.
For me FOO_LOG("stuff=" << stuff << " in loop counter #" << xyz); feels a bit unnatural. I would have to keep reffering back to the macro definition to see how it's implemented. Instead you can define a macro to behave as an std::ostream and use it as you would any other stream. That way you can do stuff like LOG_STREAM << "stuff=" << stuff << " in loop counter #" << xyz << std::endl;.
For this answer I had some inspiration from this question.
#include <fstream>
#define NDEBUG
//An ostream class that does nothing
class DummyStream : public std::ostream {
public:
int overflow(int c) { return c; }
} dummyStream;
//Here we let NDEBUG define other macros.
#ifdef NDEBUG
std::ofstream logStream;
std::ostream& oLogStream(*(std::ostream*)&logStream);
#define LOG_STREAM (logStream.is_open() ? oLogStream : dummyStream)
#define OPEN_LOG(log) (logStream.is_open() ? logStream.close(), logStream.open(log, std::ofstream::out | std::ofstream::app) : \
logStream.open(log, std::ofstream::out | std::ofstream::app))
#define CLOSE_LOG() (logStream.close())
#else
#define LOG_STREAM (dummyStream)
#define OPEN_LOG(log) //no-op
#define CLOSE_LOG() //no-op
#endif // NDEBUG
int main(int argc, char* argv[]) {
//will only log if NDEBUG is defined.
OPEN_LOG("log.txt");
std::string stuff("stuff to log");
for(int xyz = 0; xyz < 4; xyz++) {
LOG_STREAM << "stuff=" << stuff << " in loop counter #" << xyz << std::endl;
}
CLOSE_LOG();
//Log is not open so it will not log anything.
stuff = "stuff to not log";
for(int xyz = 0; xyz < 4; xyz++) {
LOG_STREAM << "stuff=" << stuff << " in loop counter #" << xyz << std::endl;
}
return 0;
}
Benifits of this?
LOG_STREAM is treated more intuitively like any other stream.
OPEN_LOG(log) will close already open logs before opening a new one and when NDEBUG is not define it will do nothing.
CLOSE_LOG() will close a log and when NDEBUG is not define it will do nothing.
Don't need to type #ifdef NDEBUG ... #endif everywhere.
dummyStream can be replaced with something like std::cout or some other stream.
Down side?
You have this DummyStream that's just in your code and a few no-op's are performed when LOG_STREAM is used when NDEBUG is not defined.
I have inherited a piece of C++ code which has many #ifdef branches to adjust the behaviour depending on the platform (#ifdef __WIN32, #ifdef __APPLE__, etc.). The code is unreadable in its current form because these preprocessor directives are nested, occur in the middle of functions and even in the middle of multi-line statements.
I'm looking for a way of somehow specifying some preprocessor tags and getting out a copy of the code as if the code had been pre-processed with those flags. I'd like the #include directives to be left untouched, though.
Example:
#include <iostream>
#ifdef __APPLE__
std::cout << "This is Apple!" << std::endl;
#elif __WIN32
std::cout << "This is Windows" << std::endl;
#endif
would turn into:
#include <iostream>
std::cout << "This is Apple!" << std::endl;
after being processed by: tool_i_want example.cpp __APPLE__.
I've hacked a quick script that does something similar, but I'd like to know of better tested and more thorough tools. I am running a Linux distribution.
I have decided against just running the C-preprocessor because if I'm not mistaken it will expand the header files, which would make everything more unreadable.
Use unifdef. It is designed for that purpose.
Complementing Basile Starynkevitch's answer, I want to mention coan. The major advantage is that, when used with -m it does not require the user to unset all symbols they want undefined.
This code:
#include <iostream>
#ifdef __ANDROID__
std::cout << "In Android" << std::endl;
#endif
#ifndef __WIN32
std::cout << "Not a Windows platform" << std::endl;
#endif
#ifdef __APPLE__
std::cout << "In an Apple platform" << std::endl;
#elif __linux__
std::cout << "In a Linux platform" << std::endl;
#endif
would result in this code if simply run as: unifdef -D__APPLE__ example.cpp:
#include <iostream>
#ifdef __ANDROID__
std::cout << "In Android" << std::endl;
#endif
#ifndef __WIN32
std::cout << "Not a Windows platform" << std::endl;
#endif
std::cout << "In an Apple platform" << std::endl;
Using unifdef one would need to use
unifdef -D__APPLE__ -U__ANDROID__ -U__WIN32 -U__linux__ example.cpp:
#include <iostream>
std::cout << "Not a Windows platform" << std::endl;
std::cout << "In an Apple platform" << std::endl;
This can get exhausting quickly when dealing with code considering several different platforms. With coan it's a matter of:
coan source -D__APPLE__ -m example.cpp.
Is there easily embeddable C++ test lib with a friendly license? I would like a single header file. No .cpp files, no five petabytes of includes. So CppUnit and Boost.Test are out.
Basically all I want is to drop single file to project tree, include it and be able to write
testEqual(a,b)
and see if it fail. I'd use assert, but it doesn't work in non-debug mode and can't print values of a and b, and before rewriting assert I'd rather search existing library.
I'm tempted to say "write your own", which is what I have done. On the other hand, you might want to reuse what I wrote: test_util.hpp and test_util.cpp. It is straightforward to inline the one definition from the cpp file into the hpp file. MIT lisence. I have also pasted it into this answer, below.
This lets you write a test file like this:
#include "test_util.hpp"
bool test_one() {
bool ok = true;
CHECK_EQUAL(1, 1);
return ok;
}
int main() {
bool ok = true;
ok &= test_one();
// Alternatively, if you want better error reporting:
ok &= EXEC(test_one);
// ...
return ok ? 0 : 1;
}
Browse around in the tests directory for more inspiration.
// By Magnus Hoff, from http://stackoverflow.com/a/9964394
#ifndef TEST_UTIL_HPP
#define TEST_UTIL_HPP
#include <iostream>
// The error messages are formatted like GCC's error messages, to allow an IDE
// to pick them up as error messages.
#define REPORT(msg) \
std::cerr << __FILE__ << ':' << __LINE__ << ": error: " msg << std::endl;
#define CHECK_EQUAL(a, b) \
if ((a) != (b)) { \
REPORT( \
"Failed test: " #a " == " #b " " \
"(" << (a) << " != " << (b) << ')' \
) \
ok = false; \
}
static bool execute(bool(*f)(), const char* f_name) {
bool result = f();
if (!result) {
std::cerr << "Test failed: " << f_name << std::endl;
}
return result;
}
#define EXEC(f) execute(f, #f)
#endif // TEST_UTIL_HPP
Try google-test https://github.com/google/googletest/
it's really light weight, cross platform and simple.