MantisBT - Doomseeker |
View Issue Details |
|
ID | Project | Category | View Status | Date Submitted | Last Update |
0003819 | Doomseeker | [All Projects] Bug | public | 2020-06-07 08:01 | 2020-06-08 14:38 |
|
Reporter | WubTheCaptain | |
Assigned To | | |
Priority | none | Severity | tweak | Reproducibility | always |
Status | acknowledged | Resolution | open | |
Platform | | OS | | OS Version | |
Product Version | 1.3.1 | |
Target Version | | Fixed in Version | | |
|
Summary | 0003819: C functions imported from <cxxx> in C++ code are not namespaced to std:: |
Description | 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. |
Steps To Reproduce | 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
|
Additional Information | '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 [^]' |
Tags | No tags attached. |
Relationships | |
Attached Files | |
|
Issue History |
Date Modified | Username | Field | Change |
2020-06-07 08:01 | WubTheCaptain | New Issue | |
2020-06-07 08:13 | WubTheCaptain | Category | Cleanup => Bug |
2020-06-07 08:15 | WubTheCaptain | Summary | C 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:16 | WubTheCaptain | Priority | normal => none |
2020-06-07 08:18 | WubTheCaptain | Additional Information Updated | bug_revision_view_page.php?rev_id=13140#r13140 |
2020-06-07 08:19 | WubTheCaptain | Additional Information Updated | bug_revision_view_page.php?rev_id=13141#r13141 |
2020-06-07 08:22 | WubTheCaptain | Note Added: 0021370 | |
2020-06-07 08:23 | WubTheCaptain | Note Edited: 0021370 | bug_revision_view_page.php?bugnote_id=21370#r13143 |
2020-06-07 08:23 | WubTheCaptain | Note Edited: 0021370 | bug_revision_view_page.php?bugnote_id=21370#r13144 |
2020-06-07 08:26 | WubTheCaptain | Note Added: 0021371 | |
2020-06-07 08:27 | WubTheCaptain | Note Edited: 0021371 | bug_revision_view_page.php?bugnote_id=21371#r13146 |
2020-06-07 08:47 | WubTheCaptain | Note Added: 0021372 | |
2020-06-07 08:47 | WubTheCaptain | Note Edited: 0021372 | bug_revision_view_page.php?bugnote_id=21372#r13148 |
2020-06-07 08:48 | WubTheCaptain | Note Edited: 0021372 | bug_revision_view_page.php?bugnote_id=21372#r13149 |
2020-06-07 08:50 | WubTheCaptain | Note Edited: 0021372 | bug_revision_view_page.php?bugnote_id=21372#r13150 |
2020-06-07 21:25 | Pol M | Note Added: 0021395 | |
2020-06-07 21:26 | Pol M | Status | new => acknowledged |
2020-06-08 00:24 | Blzut3 | Note Added: 0021400 | |
2020-06-08 02:11 | WubTheCaptain | Severity | minor => tweak |
2020-06-08 14:15 | Zalewa | Note Added: 0021442 | |
2020-06-08 14:38 | WubTheCaptain | Note Edited: 0021372 | bug_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) |
|
|
|
(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. |
|