Are you ready to join majestic world of C and C++ of programming? Do you want to question your existence after few simple lines of C++? If your answer is "Yeh!", “Yep“ or “Why not?“ - welcome to test your knowledge. You will be given multiple questions related to C or C++. Please find correct answers and explanations in the end of the story. Good luck! 1. The smallest program main; What will happen if you try to compile this program using C compiler? will not compile will compile, will not link will compile and will link 2. The fork #include <iostream> #include <unistd.h> int main() { for(auto i = 0; i < 1000; i++) std::cout << "Hello world!\n"; fork(); } How many lines will this program print? 1000 less than 1000 more than 1000 3. All you need is indices #include <iostream> int main() { int array[] = { 1, 2, 3 }; std::cout << (4, (1, 2)[array]) << std::endl; } What will this program print? 1 2 3 4 will not compile undefined 4. Regular expressions #include <regex> #include <iostream> int main() { std::regex re("(.*|.*)*O"); std::string str("0123456789"); std::cout << std::regex_match(str, re); return 0; } How long will it take for this regular expression to match this input string? 1 ms 1 sec 1 min 1 hour 1 year forever 5. Moves and lambdas #include <iostream> struct Foo { Foo() { std::cout << "Foo()\n"; } Foo(Foo&&) { std::cout << "Foo(Foo&&)\n"; } Foo(const Foo&) { std::cout << "Foo(const Foo&)\n"; } }; int main() { Foo f; auto a = [f = std::move(f)]() { return std::move(f); }; Foo f2(a()); return 0; } The last line to be printed by this program is… Foo() Foo(Foo&&) Foo(const Foo&) 6. X and bar #include <iostream> int x = 0; int bar(int(x)); int main() { std::cout << bar; } What will this program print? 0 1 0x0 will not compile will not link 7. Constructors #include <iostream> struct Foo { Foo() { std::cout << "Foo()\n"; } Foo(const Foo&) { std::cout << "Foo(const Foo&)\n"; } Foo(int) { std::cout << "Foo(int)\n"; } Foo(int, int) { std::cout << "Foo(int, int)\n"; } Foo(const Foo&, int) { std::cout << "Foo(const Foo&, int)\n"; } Foo(int, const Foo&) { std::cout << "Foo(int, const Foo&)\n"; } }; void f(Foo) {} struct Bar { int i, j; Bar() { f(Foo(i, j)); f(Foo(i)); Foo(i, j); Foo(i); Foo(i, j); } }; int main() { Bar(); } The last line to be printed by this program is… Foo(int, int) Foo(const Foo&, int) Foo(int, const Foo&) Foo(int) Instead of conclusion I hope you will never find one of this peculiar snippets in the wild. Answers The smallest program This is legal C code. It will compile and link successfully. It will crash if you try to run it. main; - is global variable.In C code you can omit a lot of things. For example you can omit the type of a global variable. By the default compiler will assume this type is an int. Also there is no name mangling in C (unlike in C++), so when linking there is no way to distinguish variable main from function main.Thus compiler will compile valid code, and linker will find something named main in object file to link a program. The fork This is more POSIX feature rather than C or C++ feature. Implementations of IO operations use buffers for optimising performance. When you invoke fork, the OS will create copy-on-write duplicate of process memory, the IO-buffers will likely duplicate as well and buffered strings likely will be printed more than 1000 times. All you need is indices Answer is 3To understand this code lets take a closer look on how indices in C and C++ work: array[index], is the same as *(array + index), is the same as (index + array) and the same as index[array.The second clue is operator,. Its binary operator, it discards left argument and returns right argument. Regular expressions Its impossible to predict what will happen! The behaviour is up to implementation.Im my environment this program raises the exception The complexity of an attempted match against a regular expression exceeded a pre-set level.Other probable options are surprisingly long time or work as expected. It’s because there are two possible approaches to implement regular expressions.First - transform regular expressions to finite automata O(n**2)(n - length of pattern), match string O(m) (m - length of string). This approach doesn’t support backtracking.Second - greedy approach + DFS, supports backtracking but prone to exponential time complexity on certain patterns. Moves and lambdas Answer is Foo(const Foo&). Lambdas are immutable by the default, all values captured into lambda with [] are implicitly const. This unlocks idempotent behaviour for lambdas.When you move f you create const Foo&&. const Foo&& is a weird type, thus compiler just copies Foo There are two ways to fix this: Create mutable lambda auto a = [f = std::move(f)]() mutable { return std::move(f); }; Declare constructor Foo(const Foo&&) X and bar The program will print 1. int bar(int(x)); — is weird way to declare function, it is equal to int bar(int x);.If you confused with type cast, int bar((int(x)));- this is type cast. Than we try to implicitly cast function address tobool, the result of such cast is always true.Functionbar() has never been used, thats allow us to dodge unreferenced symbol error while linking. Constructors The last line is Foo(const Foo&, int). Foo(i) is variable declaration, the same as Foo i. Thus class member under the name of i is hidden in this scope. Are you ready to join majestic world of C and C++ of programming? Do you want to question your existence after few simple lines of C++? If your answer is "Yeh!", “Yep“ or “Why not?“ - welcome to test your knowledge. You will be given multiple questions related to C or C++. Please find correct answers and explanations in the end of the story. Good luck! 1. The smallest program main; main; What will happen if you try to compile this program using C compiler? will not compile will compile, will not link will compile and will link will not compile will compile, will not link will compile and will link 2. The fork #include <iostream> #include <unistd.h> int main() { for(auto i = 0; i < 1000; i++) std::cout << "Hello world!\n"; fork(); } #include <iostream> #include <unistd.h> int main() { for(auto i = 0; i < 1000; i++) std::cout << "Hello world!\n"; fork(); } How many lines will this program print? 1000 less than 1000 more than 1000 1000 less than 1000 more than 1000 3. All you need is indices #include <iostream> int main() { int array[] = { 1, 2, 3 }; std::cout << (4, (1, 2)[array]) << std::endl; } #include <iostream> int main() { int array[] = { 1, 2, 3 }; std::cout << (4, (1, 2)[array]) << std::endl; } What will this program print? 1 2 3 4 will not compile undefined 1 2 3 4 will not compile undefined 4. Regular expressions #include <regex> #include <iostream> int main() { std::regex re("(.*|.*)*O"); std::string str("0123456789"); std::cout << std::regex_match(str, re); return 0; } #include <regex> #include <iostream> int main() { std::regex re("(.*|.*)*O"); std::string str("0123456789"); std::cout << std::regex_match(str, re); return 0; } How long will it take for this regular expression to match this input string? 1 ms 1 sec 1 min 1 hour 1 year forever 1 ms 1 sec 1 min 1 hour 1 year forever 5. Moves and lambdas #include <iostream> struct Foo { Foo() { std::cout << "Foo()\n"; } Foo(Foo&&) { std::cout << "Foo(Foo&&)\n"; } Foo(const Foo&) { std::cout << "Foo(const Foo&)\n"; } }; int main() { Foo f; auto a = [f = std::move(f)]() { return std::move(f); }; Foo f2(a()); return 0; } #include <iostream> struct Foo { Foo() { std::cout << "Foo()\n"; } Foo(Foo&&) { std::cout << "Foo(Foo&&)\n"; } Foo(const Foo&) { std::cout << "Foo(const Foo&)\n"; } }; int main() { Foo f; auto a = [f = std::move(f)]() { return std::move(f); }; Foo f2(a()); return 0; } The last line to be printed by this program is… Foo() Foo(Foo&&) Foo(const Foo&) Foo() Foo() Foo(Foo&&) Foo(Foo&&) Foo(const Foo&) Foo(const Foo&) 6. X and bar #include <iostream> int x = 0; int bar(int(x)); int main() { std::cout << bar; } #include <iostream> int x = 0; int bar(int(x)); int main() { std::cout << bar; } What will this program print? 0 1 0x0 will not compile will not link 0 0 1 1 0x0 0x0 will not compile will not link 7. Constructors #include <iostream> struct Foo { Foo() { std::cout << "Foo()\n"; } Foo(const Foo&) { std::cout << "Foo(const Foo&)\n"; } Foo(int) { std::cout << "Foo(int)\n"; } Foo(int, int) { std::cout << "Foo(int, int)\n"; } Foo(const Foo&, int) { std::cout << "Foo(const Foo&, int)\n"; } Foo(int, const Foo&) { std::cout << "Foo(int, const Foo&)\n"; } }; void f(Foo) {} struct Bar { int i, j; Bar() { f(Foo(i, j)); f(Foo(i)); Foo(i, j); Foo(i); Foo(i, j); } }; int main() { Bar(); } #include <iostream> struct Foo { Foo() { std::cout << "Foo()\n"; } Foo(const Foo&) { std::cout << "Foo(const Foo&)\n"; } Foo(int) { std::cout << "Foo(int)\n"; } Foo(int, int) { std::cout << "Foo(int, int)\n"; } Foo(const Foo&, int) { std::cout << "Foo(const Foo&, int)\n"; } Foo(int, const Foo&) { std::cout << "Foo(int, const Foo&)\n"; } }; void f(Foo) {} struct Bar { int i, j; Bar() { f(Foo(i, j)); f(Foo(i)); Foo(i, j); Foo(i); Foo(i, j); } }; int main() { Bar(); } The last line to be printed by this program is… Foo(int, int) Foo(const Foo&, int) Foo(int, const Foo&) Foo(int) Foo(int, int) Foo(int, int) Foo(const Foo&, int) Foo(const Foo&, int) Foo(int, const Foo&) Foo(int, const Foo&) Foo(int) Foo(int) Instead of conclusion I hope you will never find one of this peculiar snippets in the wild. Answers The smallest program This is legal C code. It will compile and link successfully. It will crash if you try to run it. main; - is global variable.In C code you can omit a lot of things. For example you can omit the type of a global variable. By the default compiler will assume this type is an int. Also there is no name mangling in C (unlike in C++), so when linking there is no way to distinguish variable main from function main.Thus compiler will compile valid code, and linker will find something named main in object file to link a program. The fork This is more POSIX feature rather than C or C++ feature. Implementations of IO operations use buffers for optimising performance. When you invoke fork, the OS will create copy-on-write duplicate of process memory, the IO-buffers will likely duplicate as well and buffered strings likely will be printed more than 1000 times. All you need is indices Answer is 3To understand this code lets take a closer look on how indices in C and C++ work: array[index], is the same as *(array + index), is the same as (index + array) and the same as index[array.The second clue is operator,. Its binary operator, it discards left argument and returns right argument. Regular expressions Its impossible to predict what will happen! The behaviour is up to implementation.Im my environment this program raises the exception The complexity of an attempted match against a regular expression exceeded a pre-set level.Other probable options are surprisingly long time or work as expected. It’s because there are two possible approaches to implement regular expressions.First - transform regular expressions to finite automata O(n**2)(n - length of pattern), match string O(m) (m - length of string). This approach doesn’t support backtracking.Second - greedy approach + DFS, supports backtracking but prone to exponential time complexity on certain patterns. Moves and lambdas Answer is Foo(const Foo&). Lambdas are immutable by the default, all values captured into lambda with [] are implicitly const. This unlocks idempotent behaviour for lambdas.When you move f you create const Foo&&. const Foo&& is a weird type, thus compiler just copies Foo There are two ways to fix this: Create mutable lambda auto a = [f = std::move(f)]() mutable { return std::move(f); }; Declare constructor Foo(const Foo&&) X and bar The program will print 1. int bar(int(x)); — is weird way to declare function, it is equal to int bar(int x);.If you confused with type cast, int bar((int(x)));- this is type cast. Than we try to implicitly cast function address tobool, the result of such cast is always true.Functionbar() has never been used, thats allow us to dodge unreferenced symbol error while linking. Constructors The last line is Foo(const Foo&, int). Foo(i) is variable declaration, the same as Foo i. Thus class member under the name of i is hidden in this scope. The smallest program This is legal C code. It will compile and link successfully. It will crash if you try to run it. main; - is global variable. In C code you can omit a lot of things. For example you can omit the type of a global variable. By the default compiler will assume this type is an int. Also there is no name mangling in C (unlike in C++), so when linking there is no way to distinguish variable main from function main. Thus compiler will compile valid code, and linker will find something named main in object file to link a program. The smallest program The smallest program This is legal C code. It will compile and link successfully. It will crash if you try to run it. main; - is global variable. It will compile and link successfully. main; In C code you can omit a lot of things. For example you can omit the type of a global variable. By the default compiler will assume this type is an int . Also there is no name mangling in C (unlike in C++), so when linking there is no way to distinguish variable main from function main . int name mangling main main Thus compiler will compile valid code, and linker will find something named main in object file to link a program. main The fork This is more POSIX feature rather than C or C++ feature. Implementations of IO operations use buffers for optimising performance. When you invoke fork, the OS will create copy-on-write duplicate of process memory, the IO-buffers will likely duplicate as well and buffered strings likely will be printed more than 1000 times. The fork The fork This is more POSIX feature rather than C or C++ feature. Implementations of IO operations use buffers for optimising performance. When you invoke fork , the OS will create copy-on-write duplicate of process memory, the IO-buffers will likely duplicate as well and buffered strings likely will be printed more than 1000 times . fork likely will be printed more than 1000 times All you need is indices Answer is 3 To understand this code lets take a closer look on how indices in C and C++ work: array[index], is the same as *(array + index), is the same as (index + array) and the same as index[array. The second clue is operator,. Its binary operator, it discards left argument and returns right argument. All you need is indices All you need is indices Answer is 3 Answer is 3 To understand this code lets take a closer look on how indices in C and C++ work: array[index] , is the same as *(array + index) , is the same as (index + array) and the same as index[array . array[index] *(array + index) (index + array) index[array The second clue is operator , . Its binary operator, it discards left argument and returns right argument. , Regular expressions Its impossible to predict what will happen! The behaviour is up to implementation. Im my environment this program raises the exception The complexity of an attempted match against a regular expression exceeded a pre-set level. Other probable options are surprisingly long time or work as expected. It’s because there are two possible approaches to implement regular expressions. First - transform regular expressions to finite automata O(n**2)(n - length of pattern), match string O(m) (m - length of string). This approach doesn’t support backtracking. Second - greedy approach + DFS, supports backtracking but prone to exponential time complexity on certain patterns. Regular expressions Regular expressions Its impossible to predict what will happen! The behaviour is up to implementation. impossible to predict Im my environment this program raises the exception The complexity of an attempted match against a regular expression exceeded a pre-set level. The complexity of an attempted match against a regular expression exceeded a pre-set level. Other probable options are surprisingly long time or work as expected. It’s because there are two possible approaches to implement regular expressions. First - transform regular expressions to finite automata O(n**2) (n - length of pattern), match string O(m) (m - length of string). This approach doesn’t support backtracking. O(n**2) O(m) backtracking. Second - greedy approach + DFS, supports backtracking but prone to exponential time complexity on certain patterns. Moves and lambdas Answer is Foo(const Foo&). Lambdas are immutable by the default, all values captured into lambda with [] are implicitly const. This unlocks idempotent behaviour for lambdas. When you move f you create const Foo&&. const Foo&& is a weird type, thus compiler just copies Foo There are two ways to fix this: Create mutable lambda auto a = [f = std::move(f)]() mutable { return std::move(f); }; Declare constructor Foo(const Foo&&) Moves and lambdas Moves and lambdas Answer is Foo(const Foo&) . Lambdas are immutable by the default, all values captured into lambda with [] are implicitly const . This unlocks idempotent behaviour for lambdas. Foo(const Foo&) [] const idempotent When you move f you create const Foo&& . const Foo&& is a weird type, thus compiler just copies Foo f const Foo&& const Foo&& Foo There are two ways to fix this: Create mutable lambda auto a = [f = std::move(f)]() mutable { return std::move(f); }; Declare constructor Foo(const Foo&&) Create mutable lambda auto a = [f = std::move(f)]() mutable { return std::move(f); }; Create mutable lambda auto a = [f = std::move(f)]() mutable { return std::move(f); }; auto a = [f = std::move(f)]() mutable { return std::move(f); }; Declare constructor Foo(const Foo&&) Declare constructor Foo(const Foo&&) Foo(const Foo&&) X and bar The program will print 1. int bar(int(x)); — is weird way to declare function, it is equal to int bar(int x);. If you confused with type cast, int bar((int(x)));- this is type cast. Than we try to implicitly cast function address tobool, the result of such cast is always true. Functionbar() has never been used, thats allow us to dodge unreferenced symbol error while linking. X and bar X and bar The program will print 1 . The program will print 1 int bar(int(x)); — is weird way to declare function, it is equal to int bar(int x); . int bar(int(x)); int bar(int x); If you confused with type cast, int bar((int(x))); - this is type cast. int bar((int(x))); Than we try to implicitly cast function address to bool , the result of such cast is always true . bool true Function bar() has never been used, thats allow us to dodge unreferenced symbol error while linking. bar() Constructors The last line is Foo(const Foo&, int). Foo(i) is variable declaration, the same as Foo i. Thus class member under the name of i is hidden in this scope. Constructors Constructors The last line is Foo(const Foo&, int) . Foo(const Foo&, int) Foo(i) is variable declaration, the same as Foo i . Thus class member under the name of i is hidden in this scope. Foo(i) Foo i i