'Is there a C++ Language Feature Mark a Variable to Prevent/Warn about Later Usage in the same Scope?
One of the common mistakes I find in C like code is the usage of a variable which is already consumed in the given scope. See the following fictive example function:
std::string normalizePath(const std::string &path) {
const auto fixedPath = fixDirectorySeparators(path);
if (fixedPath.starts_with('/')) {
return normalizeAbsolutePath(fixedPath);
}
return normalizeRelativePath(path); // use of the wrong variable.
}
In this simple function the problem is easy to spot, if it is more complex, it can be a source of errors.
The example above is oversimplified code to illustrate my question. The code could also look like this:
bool isRangeERZ(int) { ... }
int calculateNextGHA(int gha, int xfactor) {
if (xfactor > 8) {
return 0;
}
if (gha < 0x8008 || xfactor == 0) {
return gha;
}
if (gha > 0x10000) {
return xfactor;
}
int nextGha = gha * 12 * xfactor;
if (isRangeERZ(nextGha) && xfactor > 4) {
return nextGha / 4;
}
return gha; // mistake made here
}
The examples have in common, they have the same type as at least one parameter and return type.
With the introduction of the move semantics in C++11, I noticed all compilers I use easily spot obvious problems like this:
std::string moveExample() {
auto preparedString = createText(); // moved here
auto finalString = processText(std::move(preparedString));
return preparedString; // compiler warns, or stops with error.
}
Now, I wonder: Is there a language feature or a way to get the same effect, even if the variable is copied and not moved?
It could look like this:
std::string normalizePath(const std::string &path) {
const auto fixedPath = fixDirectorySeparators(std::mark_as_consumed(path));
if (fixedPath.starts_with('/')) {
return normalizeAbsolutePath(fixedPath);
}
return normalizeRelativePath(path); // Compiler warns, `path` was consumed.
}
or like this:
std::string normalizePath(const std::string &path) {
const auto fixedPath = fixDirectorySeparators(path);
std::mark_obsolete(path);
if (fixedPath.starts_with('/')) {
return normalizeAbsolutePath(fixedPath);
}
return normalizeRelativePath(path); // Compiler warns, `path` is obsolete at this point.
}
Is there already a C++ language feature (or open proposal) that helps with this kind of problem?
Solution 1:[1]
I'm not aware of any language feature that can give you what you want. You can introduce in your application the notion of Depleted/Full objects, but I wouldn't go that way. Instead, you can write your code properly:
Disclaimer: the example shows how to split the code logically and is not optimal.
std::string normalizePath(const std::string& path)
{
return normalizeFixedPath(fixDirectorySeparators(path));
}
std::string fixDirectorySeparators(const std::string& path) {...}
std::string normalizeFixedPath(const std::string& path) {
if (path.starts_with('/')) {
return normalizeAbsolutePath(path);
}
return normalizeRelativePath(path);
}
Solution 2:[2]
In short, you need a distinct list of all possible values. You might be able to get this from existing data but judging by your query, I would guess you can't.
So, create a new table, add all the options in from your case statement's 'THEN' expression which is what I assume you need (e.g. 'Stock - Purchase - NB - InterCo - UCOP', 'Stock - Purchase - NB - InterCo - EFFLUENT', etc...)
Then in your main query, just start with this table and left join you existing query to it, so the end of the statement like look something like this...
SELECT *
FROM myNewTable x
LEFT JOIN ( SELECT *
FROM [data]
WHERE journal_business_unit_code = @Business
AND bulk_details IS NOT NULL
UNION ALL
SELECT *
FROM [default]) y
ON x.myNewListOf_bulk_type = y.bulk_details
ORDER BY bulk_details
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | |
| Solution 2 | Alan Schofield |
