From: edgar <edg...@cr...> - 2021-03-22 18:33:26
|
> Hi Edgar, > > I don't think this mailing list --8<-- accept{s} attachments. I live in a bubble :P . > Second best would be to paste a diff into > the body of an email (assuming it's not too long, in which case the > first > option should be used). Third best: create a fork on notabug.org or GNU Savannah and send you the link to the corresponding branch, right? ;D In any case, below is the original suggestion. Let me know if you like the idea, and I will create the branch on notabug.org :D . Hello, I would kindly and respectfully like to suggest turning some macros in =libmesh_common.h= into functions. As I was exploring libMesh, I naïvely tried this: #+CAPTION: Using the =libmesh_error_msg= macro #+begin_src cpp :libs $(libmesh-config --cxxflags --include --ldflags --libs) #include <stdio.h> #include <iostream> #include "libmesh/libmesh.h" #include "libmesh/mesh.h" int main (int argc, char * argv[]){ libMesh::LibMeshInit init(argc, argv); if (argc < 4){ libMesh::libmesh_error_msg("Usage: "); } } #+end_src #+caption: Result from using =libmesh_error_msg= (does not compile). #+begin_example In file included from /usr/include/libmesh/libmesh.h:25, from /tmp/babel-hlBzed/C-src-YQnbkN.cpp:3: /tmp/babel-hlBzed/C-src-YQnbkN.cpp: In function 'int main(int, char**)': /tmp/babel-hlBzed/C-src-YQnbkN.cpp:15:14: error: expected unqualified-id before 'do' 15 | libMesh::libmesh_error_msg("Usage: " // << argv[0] << | ^~~~~~~~~~~~~~~~~ #+end_example This does not work, because =libmesh_error_msg= is actually a macro defined in =libmesh_common.h=, and does not need =libMesh::=. If, however, the macro is replaced with the code, it should produce: #+caption: Using the raw text from =libmesh_error_msg= #+begin_src cpp :libs $(libmesh-config --cxxflags --include --ldflags --libs) #include <stdio.h> #include <iostream> #include "libmesh/libmesh.h" #include "libmesh/mesh.h" int main (int argc, char * argv[]){ libMesh::LibMeshInit init(argc, argv); if (argc < 4){ char msg[] = "Usage: "; do { libMesh::err << msg << 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); } } #+end_src #+caption: Expected output (error message from libMesh) with raw text from =libmesh_error_msg= #+begin_example Usage: Stack frames: 5 0: libMesh::print_trace(std::ostream&) 1: libMesh::MacroFunctions::report_error(char const*, int, char const*, char const*) 2: /tmp/babel-hlBzed/C-bin-tb49Ls(+0xcdee) [0x563818bc5dee] 3: __libc_start_main 4: /tmp/babel-hlBzed/C-bin-tb49Ls(+0xceae) [0x563818bc5eae] [0] /tmp/babel-hlBzed/C-src-APc5Dz.cpp, line 22, compiled Mar 18 2021 at 17:20:53 -------------------------------------------------------------------------- MPI_ABORT was invoked on rank 0 in communicator MPI_COMM_WORLD with errorcode 1. NOTE: invoking MPI_ABORT causes Open MPI to kill all MPI processes. You may or may not see output from other processes, depending on exactly when Open MPI kills them. -------------------------------------------------------------------------- #+end_example This makes me think that we can have a function (or a template) like this: #+caption: Fuction to replace =libmesh_error_msg= macro #+begin_src cpp :libs $(libmesh-config --cxxflags --include --ldflags --libs) #include <stdio.h> #include <iostream> #include "libmesh/libmesh.h" #include "libmesh/mesh.h" void libmesh_error_msg_fun(std::string &msg) { do { libMesh::err << msg << 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); } template<typename X, typename Y> int libmesh_example_requires(X condition, Y option){ do { if (!(condition)) { libMesh::out << "Configuring libMesh with " << option << " is required to run this example." << std::endl; return 77; } } while (0); } int main (int argc, char * argv[]){ libMesh::LibMeshInit init(argc, argv); if (argc < 4){ std::string msg = {"Usage: "}; libmesh_error_msg_fun(msg); } } #+end_src #+RESULTS: #+begin_example Usage: Stack frames: 6 0: libMesh::print_trace(std::ostream&) 1: libMesh::MacroFunctions::report_error(char const*, int, char const*, char const*) 2: /tmp/babel-CpgWD6/C-bin-mEeZoe(+0xcf4f) [0x55567f87ef4f] 3: /tmp/babel-CpgWD6/C-bin-mEeZoe(+0xcd76) [0x55567f87ed76] 4: __libc_start_main 5: /tmp/babel-CpgWD6/C-bin-mEeZoe(+0xcdbe) [0x55567f87edbe] [0] /tmp/babel-CpgWD6/C-src-HfTgSq.cpp, line 18, compiled Mar 18 2021 at 20:48:30 -------------------------------------------------------------------------- MPI_ABORT was invoked on rank 0 in communicator MPI_COMM_WORLD with errorcode 1. NOTE: invoking MPI_ABORT causes Open MPI to kill all MPI processes. You may or may not see output from other processes, depending on exactly when Open MPI kills them. -------------------------------------------------------------------------- #+end_example I was expecting =libMesh::= to work as well, because =libmesh_*_msg= look very much like functions, and they are inside a =namespace=. I am sure that there is a solid reason for which they were kept as macros, and that is why this is a humble suggestion. Thank you. |