c++ questions (10 q&a)

note: iso c++ n4860 draft is used.

if something wrong with the questions, you can report via github issues.

'what's the output' means, if you see nothing wrong with the code (including ub and impl. defined situations); it would be the answer.
if not, it can be error, undefined behavior or implementation defined.

question 1: what's the output?

#include <iostream>
#include <string>

template<typename X, typename Y>
unsigned Function(X x, Y y) noexcept {
    if constexpr(std::is_same_v<X, Y>) {
        return 13;
    }

    return 0;
}

int main() {
    const int value = 13;
    enum Value: const unsigned { Val = value };
    std::cout << Function(value, Value::Val) << '\n';
}

question 2: what's the output?

#include <iostream>
#include <iomanip>

class Class {
    int Value;
public:
    explicit Class(int value) : Value(value) {}

    int GetValue() noexcept {
        return this->Value;
    }

    static inline int Function(Class value) {
        return value.GetValue();
    }
};

int main() {
    std::cout << std::boolalpha << (Class::Function('g') == static_cast<int>('g')) << '\n';
}

question 3: what's the output?

#include <iostream>
#include <vector>
#include <type_traits>
#include <iomanip>
#include <typeinfo>
#include <any>

int main() {
    std::vector<bool> Val {
        false,
        true,
        false,
        false,
        false,
        true,
        true,
        true,
    };

    std::any value = Val.front();

    std::cout << std::boolalpha << (value.type().hash_code() == typeid(bool).hash_code()) << '\n';
}

question 4: what's the output?

#include <iostream>
class Y {
public:
    Y() = default;
    ~Y() = default;

        class Z {
        public:
            Z() = default;
            ~Z() = default;
        };
};

class Q {
public:
    template<typename Val>
    void Data(Val::Z value) {
        return;
    }

    void Data(int value) {
        std::cout << value << '\n';
    }
};

int main() {
    Q q;
    q.Data(13);
}

question 5: what's the output?

int Function(int arg) noexcept {
    static int value = Function(arg + 1);
    return arg + 1;
}

int main() {
    return Function(0);
}

question 6: what's the output?


#include <iostream>

int main() noexcept((nullptr == NULL)) {
    std::cout << '0' << '\n';
    throw 0;
}

question 7: what's the output?


#include <iostream>

int main() {
    if(!nullptr) {
        std::cout <<'1'<< '\n';
    }  else {
        std::cout <<'0'<< '\n';
    }
}

question 8: what's the output?

#include <iostream>

int main() noexcept(true) {
    std::int8_t value = 255;
    ++value;
    std::cout << value << '\n';
}

question 9: what's the output?

#include <iostream>
#include <functional>

class X {
public:
    void Function(std::function<int()> func = []() {
        return 13;
    }) {
        std::cout << func() << '\n';
    }
};

int Function() {
    return 0;
}

int main() {
    X x;
    x.Function(Function);
    x.Function();
    x.Function([](){ return 2; });
}

question 10: what's the output?

template<typename X, typename Y = int>
void Function(X argument, Y argument2 = 13) {
    return;
}

int main() {
    Function<double>(13.0);
    Function<double, double>(13.0, 2.0);
    Function();
}

.
.
.
.
answers:

question 1:

9.7.1:5 [dcl.enum] says that,

      Each enumeration defines a type that is different from all other types.
      Each enumeration also has an underlying
      type. The underlying type can be explicitly specified using an enum-base. For a scoped enumeration type, the
      underlying type is int if it is not explicitly specified. In both of these cases, the underlying type is said to be
      fixed. Following the closing brace of an enum-specifier, each enumerator has the type of its enumeration. If
      the underlying type is fixed, the type of each enumerator prior to the closing brace is the underlying type and
      the constant-expression in the enumerator-definition shall be a converted constant expression of the underlying
      type (7.7). If the underlying type is not fixed, the type of each enumerator prior to the closing brace is
      determined as follows:

         — If an initializer is specified for an enumerator, the constant-expression shall be an integral constant
             expression (7.7). If the expression has unscoped enumeration type, the enumerator has the underlying
             type of that enumeration type, otherwise it has the same type as the expression.

         — If no initializer is specified for the first enumerator, its type is an unspecified signed integral type.

         — Otherwise the type of the enumerator is the same as that of the preceding enumerator unless the
             incremented value is not representable in that type, in which case the type is an unspecified integral
             type sufficient to contain the incremented value. If no such type exists, the program is ill-formed.

      so, correct answer is 0


question 2:

11.4.7.1:2 [class.conv.ctor] says that,

      ...An explicit constructor constructs objects just like non-explicit constructors, but does so only where the
      direct-initialization syntax (9.4) or where casts (7.6.1.8, 7.6.3) are explicitly used; see also 12.4.1.4. A default
      constructor may be an explicit constructor; such a constructor will be used to perform default-initialization
      or value-initialization (9.4)...

      so, this code won't be compiled due compile errors.


question 3:

22.3.12:3 [vector.bool] says that,

      There is no requirement that the data be stored as a contiguous allocation of bool values. A space-optimized
      representation of bits is recommended instead

      it's implementation defined. so depends on the compiler.


question 4:

13.10.3:1 [temp.over] and 13.10.2:7 [temp.deduct] says that,

      When a call to the name of a function or function template is written (explicitly, or implicitly using the operator
      notation), template argument deduction (13.10.2) and checking of any explicit template arguments (13.4)
      are performed for each function template to find the template argument values (if any) that can be used
      with that function template to instantiate a function template specialization that can be invoked with
      the call arguments. For each function template, if the argument deduction and checking succeeds, the
      template-arguments (deduced and/or explicit) are used to synthesize the declaration of a single function
      template specialization which is added to the candidate functions set to be used in overload resolution. If,
      for a given function template, argument deduction fails or the synthesized function template specialization
      would be ill-formed, no such function is added to the set of candidate functions for that template. The
      complete set of candidate functions includes all the synthesized declarations and all of the non-template
      overloaded functions of the same name. The synthesized declarations are treated like any other functions in
      the remainder of overload resolution, except as explicitly noted in 12.4.3.

      The substitution occurs in all types and expressions that are used in the function type and in template
      parameter declarations. The expressions include not only constant expressions such as those that appear in
      array bounds or as nontype template arguments but also general expressions (i.e., non-constant expressions)
      inside sizeof, decltype, and other contexts that allow non-constant expressions. The substitution proceeds
      in lexical order and stops when a condition that causes deduction to fail is encountered. If substitution into
      different declarations of the same function template would cause template instantiations to occur in a different
      order or not at all, the program is ill-formed; no diagnostic required. [Note: The equivalent substitution in
      exception specifications is done only when the noexcept-specifier is instantiated, at which point a program is
      ill-formed if the substitution results in an invalid type or expression...

      correct answer is 13. this state called as sfinae, which means substitution failure is not an error.


question 5:

8.8:4 [stmt.dcl] says that,

      Dynamic initialization of a block-scope variable with static storage duration (6.7.5.1) or thread storage
      duration (6.7.5.2) is performed the first time control passes through its declaration; such a variable is
      considered initialized upon the completion of its initialization. If the initialization exits by throwing an
      exception, the initialization is not complete, so it will be tried again the next time control enters the declaration.
      If control enters the declaration concurrently while the variable is being initialized, the concurrent execution
      shall wait for completion of the initialization.85 If control re-enters the declaration recursively while the
      variable is being initialized, the behavior is undefined.

      correct answer is undefined behavior.


question 6:

7.3.11:1 [conv.ptr] says that,

      A null pointer constant is an integer literal (5.13.2) with value zero or a prvalue of type std::nullptr_t. A
      null pointer constant can be converted to a pointer type; the result is the null pointer value of that type (6.8.2)
      and is distinguishable from every other value of object pointer or function pointer type. Such a conversion
      is called a null pointer conversion. Two null pointer values of the same type shall compare equal. The
      conversion of a null pointer constant to a pointer to cv-qualified type is a single conversion, and not the
      sequence of a pointer conversion followed by a qualification conversion (7.3.5). A null pointer constant of
      integral type can be converted to a prvalue of type std::nullptr_t. [Note: The resulting prvalue is not a
      null pointer value.

      so, this code won't be compiled due compile errors.


question 7:

7.3.14:1 [conv.bool] says that,

      A prvalue of arithmetic, unscoped enumeration, pointer, or pointer-to-member type can be converted to a
      prvalue of type bool. A zero value, null pointer value, or null member pointer value is converted to false;
      any other value is converted to true.

      correct answer is 1.


question 8:

7.7:5.7 [expr.const] says that,

      an operation that would have undefined behavior as specified in Clause 4 through Clause 15 of this
      document [Note: including, for example, signed integer overflow (7.2), certain pointer arithmetic (7.6.6),
      division by zero (7.6.5), or certain shift operations (7.6.7)...

      correct answer is undefined behavior.


question 9:

9.3.3.6:1 [dcl.fct.default] and 9.3.3.6:3 [dcl.fct.default] says that,

      If an initializer-clause is specified in a parameter-declaration this initializer-clause is used as a default argument.
      [Note: Default arguments will be used in calls where trailing arguments are missing (7.6.1.2)...

      A default argument shall be specified only in the parameter-declaration-clause of a function declaration
      or lambda-declarator or in a template-parameter (13.2); in the latter case, the initializer-clause shall be an
      assignment-expression. A default argument shall not be specified for a template parameter pack or a function
      parameter pack. If it is specified in a parameter-declaration-clause, it shall not occur within a declarator or
      abstract-declarator of a parameter-declaration.

      correct answer is 0 13 2.


question 10:

13.10.2:5 [temp.deduct] says that,

      The resulting substituted and adjusted function type is used as the type of the function template for template
      argument deduction. If a template argument has not been deduced and its corresponding template parameter
      has a default argument, the template argument is determined by substituting the template arguments
      determined for preceding template parameters into the default argument. If the substitution results in an
      invalid type, as described above, type deduction fails...

      so, this code won't be compiled due compile errors at 'Function()'


definitions from c++20 iso draft:

  implementation-defined behavior, 3.13 [defns.impl.defined]:

        behavior, for a well-formed program construct and correct data, that depends on the implementation and
        that each implementation document


  undefined behavior, 3.30 [defns.undefined]:

        behavior for which this document imposes no requirements

        [Note 1 to entry: Undefined behavior may be expected when this document omits any explicit definition of
        behavior or when a program uses an erroneous construct or erroneous data. Permissible undefined behavior
        ranges from ignoring the situation completely with unpredictable results, to behaving during translation or
        program execution in a documented manner characteristic of the environment (with or without the issuance
        of a diagnostic message), to terminating a translation or execution (with the issuance of a diagnostic message).
        Many erroneous program constructs do not engender undefined behavior; they are required to be diagnosed...


  unspecified behavior, 3.31 [defns.unspecified]:

        behavior, for a well-formed program construct and correct data, that depends on the implementation
        [Note 1 to entry: The implementation is not required to document which behavior occurs. The range of
        possible behaviors is usually delineated by this document...


iso c++20 n4860 draft: https://isocpp.org/files/papers/N4860.pdf

if you think about the answers or anything else is wrong,
please create an issue from github issues.