C++ Quiz from C++ Russia 2019

Hi,

We’ve recently visited a fantastic C++ Russia conference in Moscow. It gathered about 600 developers from Russia and the CIS, and several international speakers, with keynotes by Nico Josuttis and two days full of great talks. And we also had time for a C++ quiz!

This year, the JetBrains C++ team ran the quiz as an evening event on the first conference day. The quiz we prepared consisted of two parts. The first one was rather easy, so the speed of replies mattered. The second one required a more thoughtful approach and a detailed answer to each question. People asked us to publish the second part so here it is. Read each question and the code sample, and see if you can get the answer right!

Question 1: Does this code compile?

Answer: While line 6 is fine, line 9 should not compile. If you treat it as a definition of ‘x’, then an inline is missing. If you treat it as a declaration, then CTAD doesn’t work. However, GCC somehow manages to compile this code! See this: https://gcc.godbolt.org/z/sviRE5

Question 2: Does this code compile?

Answer: Both answers are acceptable. GCC fails with an Internal Compiler Error. Clang doesn’t compile, because, per Richard Smith’s comment, CTAD for nested classes is poorly described in the standard. MSVC compiles fine.

Question 3: Does this code compile?

Answer: This code should not compile. If we take a look at the vector(size_type, T) constructor, we notice the compiler infers T -> bool. Then the compiler will try to find size_type inside the vector<bool> and will fail.

Question 4: Which line contains a compilation error?

Answer: The third line contains a compilation error. From the point of view of structured bindings, a has 2 fields.

Question 5: Does this code compile?

Answer: No, it doesn’t compile. It will fail with a redefinition error, because functions that only differ in their default values for template parameters are considered equivalent.

Question 6: Does this code compile?

Answer: No, it doesn’t compile. less_than_int<short>() leads to an ambiguous function call.

Question 7: Does this code compile?

Answer: No, it doesn’t compile. The > inside enable_if_t is parsed as the end of the template arguments, not as greater sign.

Question 8: For each of the three pieces of code below, state if (by the standard) it doesn’t compile, has Undefined Behavior, or works fine.

Answer: The first piece has UB as it takes an inactive union member. The second one shouldn’t compile because anonymous structs are not described in the C++ standard, even though MSVC, GCC, and Clang support them. The third piece works, as union variants form a common initial sequence.

Question 9: In C++20, the initialization of which variable (p1, p2, q1, or q2) guarantees the output order “1”, “2”?

Answer: In lines 13 and 15, {} guarantees the evaluation (and thus printing) order. In line 16, the order cannot be guaranteed. Line 14 contains the most complicated case. We can’t even provide a proper reference to the standard’s text, but the discussion in the WG21 mailing list suggests the initialization of aggregates should guarantee the order (even with ()).

Question 10: Which of the following variables has a dangling reference (per C++20)?

Answer: Line 10 is fine – for the aggregator’s fields a temporary object lifetime extension works. Lines 12 and 13 are not that successful. Line 11 is actually interesting: the initialization of aggregates with () doesn’t give the same guarantees as with {}.

Question 11: What will be the program output? (Coroutines TS, С++20)

Answer: This program contains an Undefined Behavior, because there is a temporary object passed to the coroutine with const &. So, after the coroutine is suspended, this object is destroyed. Therefore, from the coroutine body there is a call to an already destroyed object.

Question 12: What’s wrong with the traverse function? (Coroutines TS, С++20)

Answer: The traverse function works, but asymptotically is not efficient. The tree is traversed in O(n*d), where n is the number of elements and d is depth.

Question 13: Which function will be called, #1 or #2?

Answer: This program doesn’t compile, because the argument of the requires-clause can’t be a call-expression.

Question 14: Which function will be called, #1 or #2?

Answer: This program doesn’t compile, because the argument of the requires-clause should be exactly bool, not merely convertible to bool.

Question 15: Does this code contain a redefinition error?

Answer: Clang compiles this code, but GCC does not (https://gcc.godbolt.org/z/tDmoEU). But it seems that Clang is right – since these functions are not equivalent, the requires-clause on the first line relates to the template heads, while the requires-clause on the second relates to the function itself. So, the template heads for them are different.

How many answers did you get right? Let us know!

Cheers,
Your ReSharper C++ Team

This entry was posted in Uncategorized and tagged , , , . Bookmark the permalink.

2 Responses to C++ Quiz from C++ Russia 2019

  1. me says:

    Please never make such quizzes. Your titles of questions are deceitful and badly phrased (“by the standard” might mean any standard!). Answers shouldn’t be immediately visible under the question, they should be clear, shouldn’t be based on compilation results (questions are about language, not implementation), should be consistent with the question (refer to comments and not to line numbers) and possible answers should be listed.

Leave a Reply

Your email address will not be published. Required fields are marked *