Document number |
P2951R0 |
Date |
2023-7-14 |
Reply-to |
Jarrad J. Waterloo <descender76 at gmail dot com>
|
Audience |
SG23 Safety and Security Evolution Working Group (EWG) Library Evolution Working Group (LEWG) |
Shadowing is good for safety
Table of contents
Abstract
Removing arbitrary limitations in the language associated with shadowing can improve how programmers deal with invalidation safety issues. It can also benefit a programmer’s use of const correctness which impacts immutability and thread safety concerns. Regardless, it promotes simple and succinct code.
Motivational Examples
1st request: It would be beneficial if programmers could shadow a variable with void initialization instead of having to resort to a tag class.
removing names
Present Workaround
|
Request
|
#include <string>
#include <vector>
using namespace std;
struct dename{};
int main()
{
vector<string> vs{"1", "2", "3"};
for (auto &s : vs) {
dename vs;
}
}
|
#include <string>
#include <vector>
using namespace std;
int main()
{
vector<string> vs{"1", "2", "3"};
for (auto &s : vs) {
void vs;
}
}
|
Even if this feature could not be standardized as a language feature, by removing a non breaking restriction, the tag class is adequate, provided the tag class name could be standardized as a library feature.
2nd request: It would be beneficial if programmers could initialize shadowed variables with the variable that is being shadowed.
shadowing limitation: initialization
Present and Request
|
Present Workaround
|
#include <string>
#include <vector>
using namespace std;
int main()
{
vector<string> vs{"1", "2", "3"};
for (auto &s : vs) {
const vector<string>& vs = vs;
}
return 0;
}
|
#include <string>
#include <vector>
using namespace std;
struct dename{};
int main()
{
vector<string> vs{"1", "2", "3"};
for (auto &s : vs) {
const vector<string>& vs1 = vs;
dename vs;
}
return 0;
}
|
Implementation Experience
gcc
|
this works in gcc
|
clang
|
warning: reference ‘vs’ is not yet bound to a value when used within its own initialization [-Wuninitialized]
|
msvc
|
warning C4700: uninitialized local variable ‘vs’ used
|
3rd request: It would be beneficial if programmers could shadow variables without having involve a child scope.
shadowing limitation: same level
Present and Request
|
Present Workaround
|
#include <string>
#include <vector>
using namespace std;
int main()
{
vector<string> vs{"1", "2", "3"};
const vector<string>& vs = vs;
return 0;
}
|
#include <string>
#include <vector>
using namespace std;
struct dename{};
int main()
{
vector<string> vs{"1", "2", "3"};
{
const vector<string>& vs1 = vs;
dename vs;
}
[](const vector<string>& vs)
{
}(vs);
return 0;
}
|
The error in the Present and Request
example may read something like “error: conflicting declaration ‘const vector<string> vs’//note: previous declaration as ‘vector<string> vs’”.
Summary
The advantages of adopting said proposal are as follows:
- It better allows programmers to use the compiler to avoid, debug and identify iterator, reference and pointer invalidation issues.
- This proposal aids in const correctness which is good for immutability and thread safety.
- More shadowing promotes simple and succinct code.
Frequently Asked Questions
Why dename instead of unname?
- dename : To remove the name from
- unname : To cease to name; to deprive (someone or something) of their name
While both names would work, dename seems simpler to me than unname. Personally, I think using void
would be the more intuitive C++
name.
References
Shadowing is good for safety
Jarrad J. Waterloo <descender76 at gmail dot com>
Evolution Working Group (EWG)
Library Evolution Working Group (LEWG)
Shadowing is good for safety
Table of contents
Abstract
Removing arbitrary limitations in the language associated with shadowing can improve how programmers deal with invalidation safety issues. It can also benefit a programmer’s use of const correctness which impacts immutability and thread safety concerns. Regardless, it promotes simple and succinct code.
Motivational Examples
1st request: It would be beneficial if programmers could shadow a variable with void initialization instead of having to resort to a tag class.
Present Workaround
Request
Even if this feature could not be standardized as a language feature, by removing a non breaking restriction, the tag class is adequate, provided the tag class name could be standardized as a library feature.
2nd request: It would be beneficial if programmers could initialize shadowed variables with the variable that is being shadowed.
Present and Request
Present Workaround
Implementation Experience
gcc
this works in gcc
clang
warning: reference ‘vs’ is not yet bound to a value when used within its own initialization [-Wuninitialized]
msvc
warning C4700: uninitialized local variable ‘vs’ used
3rd request: It would be beneficial if programmers could shadow variables without having involve a child scope.
Present and Request
Present Workaround
The error in the
Present and Request
example may read something like “error: conflicting declaration ‘const vector<string> vs’//note: previous declaration as ‘vector<string> vs’”.Summary
The advantages of adopting said proposal are as follows:
Frequently Asked Questions
Why dename instead of unname?
While both names would work, dename seems simpler to me than unname. Personally, I think using
void
would be the more intuitiveC++
name.References
https://en.wiktionary.org/wiki/dename ↩︎
https://en.wiktionary.org/wiki/unname ↩︎