Closed lpetre-ulb closed 4 years ago
Functions written inside the ctp7_modules cannot be used elsewhere, e.g. a standalone program.
Is it the stdsprintf
function that makes these unable to be used in a standalone program or the fact that stdsprintf
is used in many of the LOGGER
calls?
Functions written inside the ctp7_modules cannot be used elsewhere, e.g. a standalone program.
Is it the
stdsprintf
function that makes these unable to be used in a standalone program or the fact thatstdsprintf
is used in many of theLOGGER
calls?
Follow-up, and I guess more important, question where is this function defined?
Use the {fmt} library. It is designed to be small, safe and fast. Depending on the compiler the safety is provided at compile time with errors and/or at runtime with exceptions. The dependency is at compile time for the core version which a header-only library so there shouldn't be any issue with the ARM compilation.
Can you outline how this could be included in our build process? And are any additional packages required? How would working with this on the P5 technical network go (e.g. no access to the outside world).?
Is it the
stdsprintf
function that makes these unable to be used in a standalone program or the fact thatstdsprintf
is used in many of theLOGGER
calls?Follow-up, and I guess more important, question where is this function defined?
This is the stdsprintf
function itself which is the problem. It is certainly used in many LOGGER
calls but also in many more places for producing the register names. This function is defined in the rpcsvc
program source code
Use the {fmt} library. It is designed to be small, safe and fast. Depending on the compiler the safety is provided at compile time with errors and/or at runtime with exceptions. The dependency is at compile time for the core version which a header-only library so there shouldn't be any issue with the ARM compilation.
Can you outline how this could be included in our build process? And are any additional packages required? How would working with this on the P5 technical network go (e.g. no access to the outside world).?
Unfortunately, I don't know in detail how and with which constraints packages are build for P5. (If you have some documentation I'll be pleased to read it) However if the Git repository is available on the build nodes it should not be a problem.
The first important thing is that there is no dependency at runtime (except the libc++
) so no need for new package on the CTP7. At compile time there is no external dependency either, only the few {fmt}
header files are required.
While it would be possible to produce a devel
package it is much easier to simply copy the library files at a known location. I think {fmt}
is even designed to work that way (but with CMake). I would say that xhal
is a good place for it since the xcompile
directory already stores libraries used on the CTP7.
You can chose between using a Git submodule and a simple source code copy-paste. I would advise against the Git submodule though since the GitHub repository might disappear over the experiment lifetime or be inaccessible inside the P5 build network.
Proposals
- Use the {fmt} library. It is designed to be small, safe and fast. Depending on the compiler the safety is provided at compile time with errors and/or at runtime with exceptions. The dependency is at compile time for the core version which a header-only library so there shouldn't be any issue with the ARM compilation.
- Use the
stringstream
from the standard library. Syntax is however much heavier, especially for inline string formatting.
Prefer standard library options over including random dependencies unless there is a demonstrated need because of a performance bottleneck (but this is an optimization that is unlikely to be critical at this juncture in the development)
@lpetre-ulb I would suggest you make a function for this repo in include/utils.h
and include/utils.cpp
that behaves as stdsprintf
but addresses the concerns you raise here.
Then all instances of stdsprintf
can be replaced with this function. I would prefer the usage to stay the same but I'm open to alternatives.
@lpetre-ulb I would suggest you make a function for this repo in
include/utils.h
andinclude/utils.cpp
that behaves asstdsprintf
but addresses the concerns you raise here.Then all instances of
stdsprintf
can be replaced with this function. I would prefer the usage to stay the same but I'm open to alternatives.
Your function should follow from @jsturdy's comments; e.g. using STL rather than external dependency.
Any modules that I've added, I've avoided (and actually began removing) stdsprintf
and instead using stringstream
constructions.
Prefer standard library options over including random dependencies unless there is a demonstrated need because of a performance bottleneck (but this is an optimization that is unlikely to be critical at this juncture in the development)
Indeed using the standard library should be preferred. I proposed the {fmt}
library to conserve the same usage as stdsprintf
; performances were not taken into account.
After a quick look throughout the code I found many different ways of creating strings:
std::string
with concatenation operator and stringstream
to convert integers to stringsstd::string
with concatenation operator and std::to_string
stringstream
stdsprintf
After this quick review I'm convinced we should chose a standardized method. If we are going to use log4cplus
my proposal would be to use stringstream
for the logging and std::string
concatenation for register name generation (since it can easily be used as temporaries).
@lpetre-ulb I would suggest you make a function for this repo in
include/utils.h
andinclude/utils.cpp
that behaves asstdsprintf
but addresses the concerns you raise here.Then all instances of
stdsprintf
can be replaced with this function. I would prefer the usage to stay the same but I'm open to alternatives.Your function should follow from @jsturdy's comments; e.g. using STL rather than external dependency.
Writing a such function in a type-safe way with the standard library means rewriting the {fmt}
library. This a a very long and tricky development which would only reinvent the wheel.
After a quick look throughout the code I found many different ways of creating strings:
std::string
with concatenation operator andstringstream
to convert integers to stringsstd::string
with concatenation operator andstd::to_string
stringstream
stdsprintf
- and maybe other ways I missed
After this quick review I'm convinced we should chose a standardized method. If we are going to use
log4cplus
my proposal would be to usestringstream
for the logging andstd::string
concatenation for register name generation (since it can easily be used as temporaries).
Indeed.
@lpetre-ulb I would suggest you make a function for this repo in
include/utils.h
andinclude/utils.cpp
that behaves asstdsprintf
but addresses the concerns you raise here. Then all instances ofstdsprintf
can be replaced with this function. I would prefer the usage to stay the same but I'm open to alternatives. Your function should follow from @jsturdy's comments; e.g. using STL rather than external dependency.Writing a such function in a type-safe way with the standard library means rewriting the
{fmt}
library. This a a very long and tricky development which would only reinvent the wheel.
Also agree, I strongly disfavour adding an additional wrapper around something that is not at all cumbersome to do with a stringstream
Change implemented in https://github.com/cms-gem-daq-project/ctp7_modules/pull/167.
Brief summary of issue
The
rpcsvc
program provides one convenience function which is used throughout thectp7_modules
code base:stdsprintf
. This leads to 2 main issues:stdsprintf
implementation is inherently unsafe with with to the types. If the format specifier does not match the variadic argument types consequences can be disastrous.ctp7_modules
cannot be used elsewhere, e.g. a standalone program.Types of issue
Expected Behavior
Use a safe formatting library which can also be used outside of the
rpcsvc
.Current Behavior
Calls to
stdsprintf
are unsafe and depend on the `rpcsvc´ daemon.Proposals
Use the {fmt} library. It is designed to be small, safe and fast. Depending on the compiler the safety is provided at compile time with errors and/or at runtime with exceptions. The dependency is at compile time for the core version which a header-only library so there shouldn't be any issue with the ARM compilation.
Use the
stringstream
from the standard library. Syntax is however much heavier, especially for inline string formatting.