- Feature Articles
- CodeSOD
- Error'd
- Forums
-
Other Articles
- Random Article
- Other Series
- Alex's Soapbox
- Announcements
- Best of…
- Best of Email
- Best of the Sidebar
- Bring Your Own Code
- Coded Smorgasbord
- Mandatory Fun Day
- Off Topic
- Representative Line
- News Roundup
- Editor's Soapbox
- Software on the Rocks
- Souvenir Potpourri
- Sponsor Post
- Tales from the Interview
- The Daily WTF: Live
- Virtudyne
Admin
strdup() isn't standard C.
Admin
This has so many WTFs embedded. Has all the signatures of someone struggling and copying code fragments from everywhere until the output looked correct.
They probably did try the ' return "true"' pattern, but the compiler complained because it returns char * instead of const char *. So they reverted to the memory leak pattern.
Admin
That's as may be, but it also makes the code inherently broken, since double-underscores at the beginning of a C identifier (and anywhere else in C++) classes the identifier as "reserved for the system", which this code is surely not part of.
Admin
The reason might be that they will (may?) call free() on the result.
Admin
The only advantage to their
strcat
version would be returning a non-const (aka mutable) pointer. Returning theconst char*
directly would give an immutable version. However, returning a mutable buffer seems pointless as it's allocated to fit the exact size of the returned string, meaning any operations on it must copy it to a larger buffer already...Admin
Not long ago I helped to fix a code that was using
strtok()
on a string literal (yes, a homework). Kernel has been killing it with not very helpful message (at least for a beginner)... For those not familiar:strtok()
modifies in-place the string being parsed, to avoid copying. Trying to modify.rodata
/.text
memory areas (where string literals reside) is a no-no.Indeed,
const * char
is a hairy stuff, especially when the consumer mistreats it.Admin
The code given is not equivalent in practice. In the original example you must call
free
on the result, in the second one you do not have to and cannot. But you could doreturn strdup("true")
Admin
... but given that this function's job is ...
this is TRWTF. never, never, never make any assumptions of the context / environment of your function, or give instructions on how it /should/ be (properly) used.
Admin
... but given that this function's job is ...
this is TRWTF. never, never, never make any assumptions of the context / environment of your function, or give instructions on how it /should/ be (properly) used.
Admin
I've seen plenty of system code that was little better than this.
Admin
Except there still remains a WTF in that corrected code. You're returning
const
strings as non-const
theoretically allowing them to be modified, and thus invoking undefined behaviour. (Of course, any reasonably configured compiler would be pointing this out at compile time...)Admin
Exactly - came here to say this. And this is also as good a case for a ternary as I've ever seen:
const char* theRealWTFIsTheFunctionName(COMPS_Object* obj) { return ((COMPS_Num*)obj)->val ? "true" : "false"; }
Admin
"Warnings are an exercise for the reader," should be assumed any time I post my own version of the code.
Admin
Also, it doesn't even work. What works is making the function static.
Admin
You can bet the calling code doesn't call
free()
on the returned string, resulting in a memory leak... memory that should never have been allocated in the first place. I haven't coded in C (or any other low-level language) for 15 years, and I'm still shocked at how bad that code is.Admin
char *c = __comps_num2boolstr(Cobj); free(c);
Yeah, that will go over REAL good with the "improvement" suggested.......
(also, this is quite possibly from a calculation engine that uses tables of function pointers that have a consistent signatue....
Admin
Actually, I would bet against that. I've seen this pattern used before precisely so you can treat the return value the same as a dynamically allocated string and therefore not worry about whether you can free it or not.
Admin
Yeah, not much of a WTF to me, for this reason. Also, strdup() is a POSIX function, not a standard C one. We don't know about their conformance requirements, they could be targeting old and/or embedded systems.
Which leaves the naming convention as WTF, and not much else.
Addendum 2023-05-24 11:33: Ah, looks like strdup() is now a standard C function... since C23, which means it likely won't compile without warning in Visual Studio before 2035.
Admin
To be fair, this is an convention not an enforced rule. But definitely bad practice for sure.
Admin
This is wrong, that is just a clang convention
Admin
This is wrong, that is just a clang convention
Admin
No. Just no.
It long predates even the existence of clang, and is enshrined in C as early as the C89/90 standards.