From: edgar <edg...@cr...> - 2021-03-31 02:01:46
|
On 2021-03-22 19:26, edgar wrote: > On 2021-03-22 18:26, John Peterson wrote: >> The main reason that libmesh_error_msg() and friends are macros is that >> they use the __FILE__ and __LINE__ preprocessor defines to help direct the >> user to the exact place in the code where the error was triggered. I’m not >> sure if it is possible to do this same trick with inline functions, IIRC it >> will always report the line where the inline function is defined in the >> source rather than the line where it is called. > > Thank you very much, John Dear John, I checked the C++ documentation. It seems that both `__FILE__' and `__LINE__' should show up anywhere. They are also usable by functions as well. I was not planning to give more attention to this subject, but it came back to bite me when I tried to use the macro in a `void' function . So, this works: it reports the line number of the calling file, and allows the functionality that `libmesh_example_requires' and `libmesh_error_msg' provide in functions which may not be of `int' type. Again, if it convenient to have this in libMesh, I can modify `libmesh_common.h' in my local copy of the repo and push it onto <https://www.notabug.org/broncodev/libmesh> or send it to you as a diff file (the mailing list would not take attachments). ┌──── │ #include "../include/libmesh_macro_handler.h" │ #include "libmesh/libmesh.h" │ #include "libmesh/mesh.h" │ #include <iostream> │ │ using namespace libMesh; │ │ int main (int argc, char * argv[]) { │ libMesh::LibMeshInit │ init (argc, argv); │ │ libmesh_example_requires_fun(bool (0), │ "TESTME", │ __FILE__, │ __LINE__); │ // This works too (comment previous function to test) │ libmesh_error_msg_fun("FOUL"); │ │ printf("Not to be shown"); │ │ return 0; │ } └──── Listing 1: Main function ┌──── │ #ifndef LIBMESH_MACRO_HANDLER_H │ #define LIBMESH_MACRO_HANDLER_H │ │ #include <iostream> │ #include "libmesh/libmesh.h" │ #include "libmesh/libmesh_common.h" │ │ /** │ * @brief Turns =libmesh_error_msg= into a function │ * │ * @details =libmesh_error_msg= is a macro. To use │ * it inside a function, the function needs │ * to be of =int= type. This function just │ * captures the result of the macro, │ * │ * @param msg: (std::string) message to show │ * │ * @return int │ */ │ int │ libmesh_error_msg_fun(const std::string msg); │ │ /** │ * @brief Function which is equivalent to libmesh_example_requires │ * │ * @details This function allows to have the same functionality as libmesh_example_requires, but does not have a return value. Since it is not a macro, it can be called from within functions which are not of int type │ * │ * @param condition: (const bool. Ex: bool(0)) condition which needs to occur to trigger the exception handling │ * msg: (const char *. Ex: "--enable-lib") The functionality which the example requires │ * file: (const char *. Ex: __FILE__) Name of calling file │ * line: (const int. Ex: __LINE__) Line from where the exception happened in file │ * │ * @return void │ */ │ void │ libmesh_example_requires_fun (const bool condition, │ const char *msg, │ const char *file, │ const int line) { │ │ // // This would not work, because of the =void= type: │ // libmesh_example_requires (condition, option); │ │ if (!condition) { │ do { │ │ libMesh::out │ << "Configuring libMesh with " << msg │ << " is required to run this example." │ << std::endl; │ std::stringstream msg_stream; │ msg_stream << msg; │ libMesh::MacroFunctions::report_error ( │ file, line, LIBMESH_DATE, LIBMESH_TIME); │ LIBMESH_THROW ( │ libMesh::LogicError (msg_stream.str ())); │ } while (0); │ } │ } │ │ #endif /* LIBMESH_MACRO_HANDLER_H */ └──── Listing 2: header file (libmesh_macro_handle.h). Note that `libmesh_example_requires_fun' could have also been `int', but I modified it to show a stack trace too. ┌──── │ #include <stdio.h> │ #include <iostream> │ #include "libmesh/libmesh.h" │ #include "libmesh/libmesh_common.h" │ #include "../include/libmesh_macro_handler.h" │ │ int │ libmesh_error_msg_fun(const std::string msg) { │ libmesh_error_msg(msg); │ │ return 0; │ } └──── Listing 3: source file (libmesh_macro_handle.cpp) |