2
#include <iostream>
struct A{
    operator int(){
        return 0;
    }
};
int main(){
    A a;
    a;  //#1
    (int)a; //#2
    (A)a; //#3
}

In the above example, #1 and #2 can both trigger Clang to emit the "expression result unused" warning but #3 does not.
What I am concerning here is that these three expressions are all discarded-value expressions, that is, the values of these glvalues are all discarded, as per expr.context#2

In some contexts, an expression only appears for its side effects. Such an expression is called a discarded-value expression. The array-to-pointer and function-to-pointer standard conversions are not applied. The lvalue-to-rvalue conversion is applied if and only if the expression is a glvalue of volatile-qualified type and it is one of the following:

  • [...]

If the (possibly converted) expression is a prvalue, the temporary materialization conversion is applied. The glvalue expression is evaluated and its value is discarded.

Presumably, Clang will emit the warning when the value of a glvalue is discarded.

At #1, the glvalue is discarded, hence Clang emits the warning.

At #2, since the expression is a prvalue, the materialization conversion applies to it to be a glvalue, and the value of such a glvalue is discarded. It has the same reason as that of #1.

Now, consider #3, the effect likes static_cast<A>(a), which is a prvalue. Hence the materialization conversion still applies to it, then it becomes a glvalue, the same reason should make Clang emit the warning.

Although, "expression result unused" is not ruled by the standard, what I am concerning here is just whether it is reasonable that Clang didn't emit the warning for #3.

cigien
  • 57,834
  • 11
  • 73
  • 112
xmh0511
  • 7,010
  • 1
  • 9
  • 36
  • @Zoso That's a bit weird here. It's not reasonable that `#3` and `#4` have different behavior. – xmh0511 Apr 09 '21 at 05:56
  • GCC appears to just overlook all except #1...which is even weirder [link](https://godbolt.org/z/a53qdTEv6) but then it's not mandated by the standard so... – Zoso Apr 09 '21 at 06:02
  • 2
    Not only (these kinds of) warnings are not mandated by the standard, they aren't even suggested nor mentioned. I personally don't understand why you are "concerned". Warnings will never be exhaustive and we will never get warnings for all human errors. A lot of errors will get by without warnings and that is just a fact of life. The compiler can help with warnings suggestions, but the human is ultimately responsible for the code (that is until the AI overloads take over). Curios case? Yes! Interesting? Maybe. Helpful to fix? Yes! Concerning? No! Anyway, that' just my take on it. – bolov Apr 09 '21 at 06:07
  • 1
    @bolov As I said in my question, I expect that the behavior of Clang when encountering these codes that would have the same effect should be consistent. – xmh0511 Apr 09 '21 at 06:14
  • @xmh0511 that is a reasonable expectation. I also have the same expectation. But for me the fact that it doesn't happen I see it as a quirk of clang, not a reason for "concern". – bolov Apr 09 '21 at 06:21
  • @bolov If A and B have the same category, however, we impose `A` and `B` with different treatment; Is that reasonable? – xmh0511 Apr 09 '21 at 06:26
  • You could open an issue about this (at the Clang site). Maybe, one of the authors may comment on this, or they even consider to fix this. @bolov Although I do support your reasoning, I understand the concerns of OP. How much concerns somebody has may depend on the personal paranoia. IMHO, a bit paranoia couldn't hurt in a language with U.B. at every next corner... ;-) – Scheff's Cat Apr 09 '21 at 06:53
  • 1
    I am afraid I am not getting my point across. I am not contesting the fact that #1 #2 and #3 should probably be treated the same. What I am saying is that the fact that they are not treated the same is not a reason for concern. C++ is a **very**, **very** and I cannot emphasize this enough, **very** difficult language to parse. I will go a bit on a tangent next, but please bear with me. [...] – bolov Apr 09 '21 at 06:58
  • [...] The grammar mentioned in the standard may be **context-free**, but that grammar is not enough to describe the C++ language and there are a lot of intricate rules on top of that grammar to define a correct C++ program and that [makes](https://stackoverflow.com/questions/14589346/) the C++ language a Type-0 grammar ("unrestricted") in the Chomsky hierarchy. Often what is "obvious" for a human is far from obvious to a parser/compiler. [...] – bolov Apr 09 '21 at 06:58
  • [...] Oddities like the one you found are most likely caused due to one of 2 causes: complicated parsing case/complicated AST or a simple omission on the compiler part. Neither of which is a reason for concern in my book. – bolov Apr 09 '21 at 06:58
  • Or maybe I don't understand you. Why do you find this "concerning"? What is your fear? – bolov Apr 09 '21 at 07:18
  • 1
    If possible, one should make it a habit to also use dedicated static analysis tools on code, as it could find things the compiler might overlook (for example because it's out of scope of the compiler, or because such analysis is too expensive for the compilator). – Some programmer dude Apr 09 '21 at 07:27
  • Your statement "*Although, "expression result unused" is not ruled by the standard, what I am concerning here is just whether it is reasonable that Clang ...*" makes this not a language-lawyer question since you're not asking for an interpretation of the standard. – cigien Apr 09 '21 at 15:03

0 Answers0