language-lawyer

Does calling printf without a proper prototype invoke undefined behavior?

大兔子大兔子 提交于 2019-12-23 09:40:45
问题 Does this innocent looking program invoke undefined behavior: int main(void) { printf("%d\n", 1); return 0; } 回答1: Yes invoking printf() without a proper prototype (from the standard header <stdio.h> or from a properly written declaration) invokes undefined behavior. As documented in C11 Annex J (informative only) J2 Undefined Behavior For call to a function without a function prototype in scope where the function is defined with a function prototype, either the prototype ends with an

Wrong overload called when constructing from initializer_list inside parentheses

北战南征 提交于 2019-12-23 09:39:30
问题 I always thought that when I use initializer list C++ syntax like: something({ ... }); it's always clear to the compiler that I want to call the overload taking an std::initializer_list , but it seems this is not so clear for MSVC 2015. I tested this simple code: #include <cstdio> #include <initializer_list> namespace testing { template<typename T> struct Test { Test() { printf("Test::Test()\n"); } explicit Test(size_t count) { printf("Test::Test(int)\n"); } Test(std::initializer_list<T> init

Template instantiation, two-phase name lookup, different behavior with automatic deduced type

瘦欲@ 提交于 2019-12-23 09:19:49
问题 After seeing this question When is a C++ template instantiation type checked? , and wondering myself for quite some time the same thing I started to play with code to assimilate the knowledge. The answer gives clear and correct explanation. It mentions two-phase name lookup and the fact that the end of translation unit is also considered a point of instantiation for function templates. However I observed different behavior when using automatic return type deduction: This is like the original

Forwarding template taking precedence over overload

試著忘記壹切 提交于 2019-12-23 09:03:56
问题 I thought that a non-template would always take precedence over a template, if the arguments match up just as well. But: template <typename... Args> void Trace(Args&&... args) { throw "what the frak"; } void Trace(const int&) {} int main() { Trace(42); } This throws unless I make the non-template Trace(int) or Trace(int&&) , i.e. not taking a const ref. It's kind of annoying because I want to provide a different implementation for specific argument types where the real implementation of the

Returning a variable while using a post increment in C

巧了我就是萌 提交于 2019-12-23 08:56:08
问题 I have a global variable called var and a function foo . (I know it's a bad practice but sometimes it's unavoidable) I'm wondering if the C standard (I'm compiling using c99) says what happens to var if I try to execute: long foo(){ return var++; } Thanks. 回答1: Short answer: It will return a copy of var and then immediately afterwards increment the global var . Long answer: C11 6.5.2.4 "The result of the postfix ++ operator is the value of the operand. As a side effect, the value of the

What is lub(null, Double)?

半世苍凉 提交于 2019-12-23 08:45:39
问题 Table 15.25-B in JLS version 8 says that the type of a conditional expression true ? null : 0.0 is lub(null,Double) , where lub appears to be some crazy incomprehensible thing from section 4.10.4. This appears to be distinct from the Double type somehow, or they probably would have just written Double , like they did elsewhere in the table. It's not clear what the difference could be, though. I tried to work it out from section 4.10.4, but by the time I got to the part about Let lub(U1 ... Uk

Why C++ template accepting array is not more specialized than one accepting pointer (bis)?

徘徊边缘 提交于 2019-12-23 08:03:05
问题 In reference to this question, which has indeed the same title but for which I found an answer in the standard. I have continued to dig the subject and finaly find out an example code for which this answer does not apply. Let's consider this piece of code: template<class T> void func(T* buf); //template I template<size_t N> void func(char (&buf) [N]); //template II void g(char (&buf)[3]) { func(buf) //Error: ambiguous function call (Clang, GCC, ICC, MSVC) } According to the partial ordering

Why no transparent C++1x std::map::at?

天大地大妈咪最大 提交于 2019-12-23 07:57:46
问题 Is there a reason for missing transparent ( template <class K> at(K&& key); ) in std::map ? 回答1: My guess is that std::map::at() must be a "bounds-checked" version of std::map::operator[]() . Providing a transparent version of std::map::operator[]() imposes an additional requirement on std::map::key_type and the query key type K - if the query key is not in the map, it must be inserted (with default constructed value), which means that std::map::key_type must be constructible from the the

Inherited constructors, default constructor and visibility

老子叫甜甜 提交于 2019-12-23 07:49:10
问题 As stated by [namespace.udecl]/18: [...] A using-declaration that names a constructor does not create a synonym; instead, the additional constructors are accessible if they would be accessible when used to construct an object of the corresponding base class, and the accessibility of the using-declaration is ignored. [...] Because of that, the following code does not compile: class B { protected: B(int) { } }; class D: B { using B::B; }; int main () { D d{0}; } It returns an error that is more

What is the expected output when redefining true to false and vice versa?

佐手、 提交于 2019-12-23 07:46:39
问题 #include <iostream> #define true false #define false true int main() { std::cout << false << true; } Why does it output "01"? 回答1: As Jerry Coffin notes, you cannot define a macro with a name that is a keyword. However, we could consider another, similar example, with well-defined behavior and the same result. Consider: int TRUE = 1; int FALSE = 0; #define TRUE FALSE #define FALSE TRUE std::cout << FALSE << TRUE; When you use FALSE , it is identified as the macro FALSE and is replaced by that