MantisBT - Doomseeker
View Issue Details
0003819Doomseeker[All Projects] Bugpublic2020-06-07 08:012020-06-08 14:38
WubTheCaptain 
 
nonetweakalways
acknowledgedopen 
1.3.1 
 
0003819: C functions imported from <cxxx> in C++ code are not namespaced to std::
I guess this is a standard violation, but didn't bother digging up the section or quote from it.
Quote from https://developers.redhat.com/blog/2016/02/29/why-cstdlib-is-more-complicated-than-you-might-think/
By the mid-2000s, a carefully written C++ program could use the common intersection of conforming and non-conforming C++ implementations and be mostly portable between implementations. Such code needed to consistently use std:: to qualify names after including a <cxxx> header, and consistently not qualify names after including a <xxx.h> header. But in the real world, developers aren’t always so careful. Even if they are aware of the precise requirements of the standard, it’s easy to accidentally use strlen (without qualification) after including <cstring>, and if the code compiles then it will get shipped. This meant that millions of lines of C++ code were unwittingly relying on properties of their implementation which violated the standard, creating a serious portability problem.

And today C++ compilers/standard libraries have coped by implementing C functions namespaced and unnamespaced.
Take for example the following file/quote:
Quote from src/core/scanner.cpp
void Scanner::scriptMessage(MessageLevel level, const char *error, ...) const
{
        /* ... */

        sprintf(newMessage, "%s:%d:%d:%s: %s\n", d->scriptIdentifier.toUtf8().constData(), 
currentLine(), currentLinePos(), messageLevel, error);
        va_list list;
        va_start(list, error);
        if (messageHandler)
                messageHandler(level, newMessage, list);
        else
                vfprintf(stderr, newMessage, list);
        va_end(list);

        /* ... */
}


C macros va_* and functions *printf() should be std::va_* and std::*printf() respectively. (Not pointers, but match all.) Because:
Quote from src/core/scanner.cpp
#include <cmath>
#include <cstdio>
#include <cstdlib>

If these were <xxx.h> files, they would be allowed to pollute the global namespace. But that's also deprecated according to C++ standard (for compatibility only).
Likely many more files than just src/core/scanner.cpp. Also relevant (but a result of 0 is good practice):
$ grep -r "using namespace std" src/ | wc -l
0

An example metric (because I know Doomseeker uses <cstdio> instead of <iostream> everywhere):
$ grep -r "std::printf" src/ | wc -l
0

'https://developers.redhat.com/blog/2016/02/29/why-cstdlib-is-more-complicated-than-you-might-think/ [^]'
'https://stackoverflow.com/a/28227068 [^]'
'https://stackoverflow.com/a/32606280 [^]'
No tags attached.
Issue History
2020-06-07 08:01WubTheCaptainNew Issue
2020-06-07 08:13WubTheCaptainCategoryCleanup => Bug
2020-06-07 08:15WubTheCaptainSummaryC functions from C++ code are not namespaced to std:: => C functions imported from <cxxx> in C++ code are not namespaced to std::
2020-06-07 08:16WubTheCaptainPrioritynormal => none
2020-06-07 08:18WubTheCaptainAdditional Information Updatedbug_revision_view_page.php?rev_id=13140#r13140
2020-06-07 08:19WubTheCaptainAdditional Information Updatedbug_revision_view_page.php?rev_id=13141#r13141
2020-06-07 08:22WubTheCaptainNote Added: 0021370
2020-06-07 08:23WubTheCaptainNote Edited: 0021370bug_revision_view_page.php?bugnote_id=21370#r13143
2020-06-07 08:23WubTheCaptainNote Edited: 0021370bug_revision_view_page.php?bugnote_id=21370#r13144
2020-06-07 08:26WubTheCaptainNote Added: 0021371
2020-06-07 08:27WubTheCaptainNote Edited: 0021371bug_revision_view_page.php?bugnote_id=21371#r13146
2020-06-07 08:47WubTheCaptainNote Added: 0021372
2020-06-07 08:47WubTheCaptainNote Edited: 0021372bug_revision_view_page.php?bugnote_id=21372#r13148
2020-06-07 08:48WubTheCaptainNote Edited: 0021372bug_revision_view_page.php?bugnote_id=21372#r13149
2020-06-07 08:50WubTheCaptainNote Edited: 0021372bug_revision_view_page.php?bugnote_id=21372#r13150
2020-06-07 21:25Pol MNote Added: 0021395
2020-06-07 21:26Pol MStatusnew => acknowledged
2020-06-08 00:24Blzut3Note Added: 0021400
2020-06-08 02:11WubTheCaptainSeverityminor => tweak
2020-06-08 14:15ZalewaNote Added: 0021442
2020-06-08 14:38WubTheCaptainNote Edited: 0021372bug_revision_view_page.php?bugnote_id=21372#r13192

Notes
(0021370)
WubTheCaptain   
2020-06-07 08:22   
(edited on: 2020-06-07 08:23)
Quote from https://stackoverflow.com/a/32606280
The header <cstdlib> assuredly provides its declarations and definitions within the namespace std. It may also provide these names within the global namespace. The header <stdlib.h> assuredly provides the same declarations and definitions within the global namespace, much as in the C Standard. It may also provide these names within the namespace std.

So technically valid, but still quite possibly deprecated.
Quote from https://stackoverflow.com/a/32606280
In other words: prefer
#include <cstdio>

int main() {
    std::printf("Hello world\n");
}

over
#include <stdio.h>

int main() {
    printf("Hello world\n");
}

Which is also true (that <cxxx> headers should be preferred over deprecated <xxx.h> headers).

(0021371)
WubTheCaptain   
2020-06-07 08:26   
(edited on: 2020-06-07 08:27)
[Off-topic:] And as noted in Stack Overflow comments to said answer, that might change again with C++20 (with a strong recommendation to undeprecate them) soon:'http://open-std.org/JTC1/SC22/WG21/docs/papers/2017/p0619r0.html#3.5 [^]'

(0021372)
WubTheCaptain   
2020-06-07 08:47   
(edited on: 2020-06-08 14:38)
Quote from https://developers.redhat.com/blog/2016/02/29/why-cstdlib-is-more-complicated-than-you-might-think/
This non-conformance issue was so widespread among C++ implementations, and the portability problem affected so much code, that for the 2011 revision of the C++ standard (aka C++11) the ISO C++ committee took the pragmatic step of deciding that the common approach was a valid implementation strategy. Thanks to Library Working Group (LWG) Defect Report 456 it is now unspecified whether `<cxxx>` headers include `<xxx.h>` and import names from the global namespace to namespace `std`, or vice versa.

So technically, OP is right to conform to C++98. Since C++11, it doesn't matter.
Technically Doomseeker is still claiming to compile to C++98 standard (despite ISO also saying the latest version is *the standard*). And I don't care if C++11 changes that, using std:: is the most portable way it seems.
The fact g++ compiles in -std=c++98 without a warning is questionable in itself.

(0021395)
Pol M   
2020-06-07 21:25   
I don't mind either way tbh :)
Given that these headers are going to pollute the global namespace either way, I don't blame anyone to use the global symbols as that cuts on characters.
(0021400)
Blzut3   
2020-06-08 00:24   
Although I'm sure there's some pedantic code base out there, I know of literally no one that prefixes std C functions with std::.
(0021442)
Zalewa   
2020-06-08 14:15   
Unless this causes some actual compilation problems (errors or warnings) I don't think we should "fix" this. This doesn't look much different to me than "tabs vs. spaces", "explicit this->" vs. "implicit this->" or 0003815. I simply see no benefits in doing the change.