'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