TString::Form(const char* fmt, ...) is not a static function and has return type
void, I don’t understand how code like this does not break and actually produces the formatted output:
int i = 1;
std::string s(Form("Test %d", i));
std::cout << s << std::endl;
The code above does run and outputs “Test 1”, both in interpreted and compiled modes (with ROOT 5 and 6, using clang or gcc). The syntax
std::string s = Form("Test %d", i); or
const char* cs = Form("Test %d", i); also work.
This really puzzles me. It seems like my understanding of the C++ language is the problem here.
I wonder if the above syntax is safe, as using it instead of
std::string s = TString::Format( ... ).Data() would produce more concise and readable code.
There are multiple functions called TString::Form, one which is an member method and one which is a static method. The member method does indeed have a return type of void since it modifies the TString e.g
TString str ("");
str.Form("Some format string");
The second, static method, is the one that is called in your example. It has a return type of
char * and is used as
TString str = Form("Some string");
Unfortunately the documentation for the latter seems to be missing from the reference documentation. A sibling function TString::Format is available and is very similar to the TString::Form function; They differ only in return type.
You can check TString.h if you want to go to the bottom of this yourself
Thank you for your answer. Looking at the TString header, it seems that
Form is even defined as a global function (not a static member of TString).
extern char *Form(const char *fmt, ...)
It could be useful to mention it in the documentation of either TString::Form or TString::Format.
To summarize. There are 4 similar functions. 2 are member functions of the class TString and 2 are in the global namespace.
TString::Form : static function returns a temporary TString object
TString::Format : member function modifying a TString object
::Form, ::Format : different in argument only, return a const char* that is inside a thread local character buffer.
The usage of TString::Form, ::Form and ::Format is similar. Using the later two, you need to make sure that the result is not being passed to a function that itself will call one of these two functions as it would ‘overwrite’ the buffer while it is being used. These two functions date back to a time when creating temporary object and especially copying them (i.e. no move semantic) was very expansive.
Nowadays the recommendation is simple, just use TString::Form or TString::Format. For example:
formatted.Form("%s in <%s>: %s", type, location, msg);
lines.emplace_back(TString::Format("Welcome to ROOT %s%%shttp://root.cern.ch",
This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.