A particular property of c++'s lambda expressions is to capture the variables in the scope in which they are declared. For example I can use a declared and initialized variable c in a lambda function even if 'c' is not sent as an argument, but it's captured by '[ ]':
#include<iostream>
int main ()
{int c=5; [c](int d){std::cout<<c+d<<'\n';}(5);}
The expected output is thus 10. The problem arises when at least 2 variables, one captured and the other sent as an argument, have the same name:
#include<iostream>
int main ()
{int c=5; [c](int c){std::cout<<c<<'\n';}(3);}
I think that the 2011 standard for c++ says that the captured variable has the precedence on the arguments of the lambda expression in case of coincidence of names. In fact compiling the code using GCC 4.8.1 on Linux the output I get is the expected one, 5. If I compile the same code using apple's version of clang compiler (clang-503.0.40, the one which comes with Xcode 5.1.1 on Mac OS X 10.9.4) I get the other answer, 3.
I'm trying to figure why this happens; is it just an apple's compiler bug (if the standard for the language really says that the captured 'c' has the precedence) or something similar? Can this issue be fixed?
EDIT
My teacher sent an email to GCC help desk, and they answered that it's clearly a bug of GCC compiler and to report it to Bugzilla. So Clang's behavior is the correct one!
From my understanding of the c++11 standard's points below:
5.1.2 Lambda expressions
3 The type of the lambda-expression (which is also the type of the closure object) is a unique, unnamed non-union class type — called
the closure type — whose properties are described below.
...
5 The closure type for a lambda-expression has a public inline function call operator (13.5.4) whose parameters and return type are
described by the lambda-expression’s parameter-declaration-clause and
trailing-return-type respectively. This function call operator is
declared const (9.3.1) if and only if the lambda-expression’s
parameter-declaration-clause is not followed by mutable.
...
14 For each entity captured by copy, an unnamed non static data member is declared in the closure type
A lambda expression like this...
int c = 5;
[c](int c){ std::cout << c << '\n'; }
...is roughly equivalent to a class/struct like this:
struct lambda
{
int c; // captured c
void operator()(int c) const
{
std::cout << c << '\n';
}
};
So I would expect the parameter to hide the captured member.
EDIT:
In point 14 from the standard (quoted above) it would seem the data member created from the captured variable is * unnamed *. The mechanism by which is it referenced appears to be independent of the normal identifier lookups:
17 Every id-expression that is an odr-use (3.2) of an entity captured by copy is transformed into an access to the corresponding unnamed data member of the closure type.
It is unclear from my reading of the standard if this transformation should take precedence over parameter symbol lookup.
So perhaps this should be marked as UB (undefined behaviour)?
From the C++11 Standard, 5.1.2 "Lambda expressions" [expr.prim.lambda] #7:
The lambda-expression’s compound-statement yields the function-body (8.4) of the function call operator,
but for purposes of name lookup (3.4), determining the type and value of this (9.3.2) and transforming id-expressions
referring to non-static class members into class member access expressions using (*this) (9.3.1),
the compound-statement is considered in the context of the lambda-expression.
Also, from 3.3.3 "Block scope" [basic.scope.local] #2:
The potential scope of a function parameter name (including one appearing in a lambda-declarator) or of
a function-local predefined variable in a function definition (8.4) begins at its point of declaration.
Names in a capture list are not declarations and therefore do not affect name lookup. The capture list just allows you to use the local variables; it does not introduce their names into the lambda's scope. Example:
int i, j;
int main()
{
int i = 0;
[](){ i; }; // Error: Odr-uses non-static local variable without capturing it
[](){ j; }; // OK
}
So, since the parameters to a lambda are in an inner block scope, and since name lookup is done in the context of the lambda expression (not, say, the generated class), the parameter names indeed hide the variable names in the enclosing function.
Related
#include <string>
struct T1 {
int _mem1;
int _mem2;
T1() = default;
T1(int mem2) : T1() { _mem2 = mem2; }
};
T1 getT1() { return T1(); }
T1 getT1(int mem2) { return T1(mem2); }
int main() {
volatile T1 a = T1();
std::printf("a._mem1=%d a._mem2=%d\n", a._mem1, a._mem2);
volatile T1 b = T1(1);
std::printf("b._mem1=%d b._mem2=%d\n", b._mem1, b._mem2);
// Temporarily disable
if (false) {
volatile T1 c = getT1();
std::printf("c._mem1=%d c._mem2=%d\n", c._mem1, c._mem2);
volatile T1 d = getT1(1);
std::printf("d._mem1=%d d._mem2=%d\n", d._mem1, d._mem2);
}
}
When I compile this with gcc5.4, I get the following output:
g++ -std=c++11 -O3 test.cpp -o test && ./test
a._mem1=0 a._mem2=0
b._mem1=382685824 b._mem2=1
Why does the user defined constructor, which delegates to the default constructor not manage to set _mem1 to zero for b, however a which uses the default constructor is zero initialized?
Valgrind confirms this also:
==12579== Conditional jump or move depends on uninitialised value(s)
==12579== at 0x4E87CE2: vfprintf (vfprintf.c:1631)
==12579== by 0x4E8F898: printf (printf.c:33)
==12579== by 0x4005F3: main (in test)
If I change if(false) to if(true)
Then the output is as you would expect
a._mem1=0 a._mem2=0
b._mem1=0 b._mem2=1
c._mem1=0 c._mem2=0
d._mem1=0 d._mem2=1
What is the compiler doing?
Short answer: for trivial types, the two distinct forms of "default construction" leads to two different initializations:
T a; in which case the object is default-initialized. Its value is undetermined and undefined behavior will soon happen (this is how is initialized b.mem1 and why valgrind detect an error.)
T a=T(); in which case the object is value-initialized and its entire memory is zeroed (this is what happens to a.mem1 and a.mem2)
Long answer: Actualy, the default constructor of T1 is not the cause of zero initialization of a.mem1. a has been first zero-initialized but not b because of a singular rule of the standard that does not apply for b's initializer.
The definition volatile a=T() causes a to be value-initialized (1). struct T1 as no user-provided default constructor (2). For such a struct the entire object is zero-initialized as stated by this rule of the C++11 standard [dcl.init]/7.2:
if T is a (possibly cv-qualified) non-union class type without a user-provided constructor, then the object is zero-initialized and, if T's implicitly-declared default constructor is non-trivial, that constructor is called.
There is a subtle difference between C++11 and C++17 that causes the definition volatile b=T(1) to be undefined behavior in C++11 but not in C++17. In C++11, b is initialized by copying an object type T1 which is initialized by the expression T(1). This copy construction evaluate T(1).mem1 which is an undetermined value. This is forbidden. In c++17, b is directly initialized by the prvalue expression T(1).
The evaluation of this undetermined value inside the printf is also undefined behavior independently of the c++ standard. This is why valgrind complains and why you see inconsistent outputs when you change if (true) to if (false).
(1) strictly speaking a is copy constructed from a value-initalized object in c++11
(2) T1's default constructor is not user provided because it is defined as defaulted on the first declaration
Short Answer
The default constructor in your code is considered trivial and that kind of constructor perform no actions i.e. leave things unitialized.
Longer answer
Trivial default constructor
The default constructor for class T is trivial (i.e. performs no
action) if all of the following is true:
The constructor is not user-provided (i.e., is implicitly-defined or defaulted on its first declaration)
T has no virtual member functions
T has no virtual base classes
T has no non-static members with default initializers.
(since C++11)
Every direct base of T has a trivial default constructor
Every non-static member of class type has a trivial default constructor
> A trivial default constructor is a constructor that performs no
action. All data types compatible with the C language (POD types) are
trivially default-constructible. Unlike in C, however, objects with
trivial default constructors cannot be created by simply
reinterpreting suitably aligned storage, such as memory allocated with
std::malloc: placement-new is required to formally introduce a new
object and avoid potential undefined behavior.
http://www.enseignement.polytechnique.fr/informatique/INF478/docs/Cpp/en/cpp/language/default_constructor.html
I have the following code which work fine. I am trying to understand the syntax. The return statement has std::plus<double>(). The double over here has the return value data type. But the function definition has the return type as std::function<double(double, double)> which indicates two double parameters. How do these two relate to each other?
#include <functional>
#include <iostream>
using namespace std;
std::function<double(double, double)> GetFunction()
{
return std::plus<double>();
}
int main()
{
auto operation = GetFunction();
int a = operation(1, 4);
std::cout << std::plus<>{}(1, 4) << '\n';
return 0;
}
There is an implicit conversion from std::plus<double> to std::function<double(double,double)>, because the former has a member call operator double operator()(double, double). See the documentation for std::function constructors.
In std::function<double(double, double)>:
The first double is the return type of the function. You can remember that by realizing that it's on the left, just like in a normal function definition.
The doubles in parentheses are the parameter types of the function, just like in a normal function definition; minus the parameter names. There are 2 since the plus function takes 2 doubles.
This makes sense if you think about it. The plus function/operator is a binary operator, meaning it takes 2 parameters of a type, and returns a single value of the same type. This is why you only need to specify a single type when you write std::plus<double>; the parameters and the return type must be the same type. It would be error prone and useless to force the caller to specify the same type 3 times.
If your question is, why there is only one double in the template parameter of std::plus but three in std::function, then the answer is this:
For std::plus, both parameters and the returntype always have to be the same, so you only have to specify it once.
std::function on the other hand can hold any function like object with any combination of parameters and returntypes, so you have to basically state each of those types individually.
I am curious why, in C++ 11, use of "= default" on a derived virtual method does not select the pure base class implementation.
For example, the following test code produces the message "error: 'virtual void B::tst()' cannot be defaulted" from "g++ -std=c++11".
struct A {
virtual ~A () = default;
virtual void tst () = 0;
};
void A :: tst () {}
struct B : public A {
virtual void tst () = default;
};
We can of course provide a B::tst that invokes the default base implementation, but one is concerned that this might be the higher overhead implementation compared to a hypothetical "= default" based coding.
Sorry to ask questions about what might or might not be within the minds of the c++ standards committee persons, but nevertheless perhaps someone here at stack overflow will have some wisdom concerning the impracticality of using the default keyword in this way that would be interesting to hear.
Thanks!
According to the standard §8.4.2/p1 Explicitly-defaulted functions [dcl.fct.def.default] (Emphasis Mine):
A function definition of the form:
attribute-specifier-seqopt decl-specifier-seqopt declarator
virt-specifier-seqopt = default;
is called an explicitly-defaulted definition. A function that is
explicitly defaulted shall
(1.1) — be a special member function,
(1.2) — have the same declared function type (except for possibly differing ref-qualifiers and except that in
the case of a copy constructor or copy assignment operator, the parameter type may be “reference to
non-const T”, where T is the name of the member function’s class) as if it had been implicitly declared,
and
(1.3) — not have default arguments
Member function tst() is not a special member function. Thus, it cannot be defaulted.
Now specifying a member function of a class (e.g., class A) as pure virtual entails that any class that inherits from that class and you don't wan't it to be abstract as well must override that member function.
TypeScript has a bunch of different ways to define an enum:
enum Alpha { X, Y, Z }
const enum Beta { X, Y, Z }
declare enum Gamma { X, Y, Z }
declare const enum Delta { X, Y, Z }
If I try to use a value from Gamma at runtime, I get an error because Gamma is not defined, but that's not the case for Delta or Alpha? What does const or declare mean on the declarations here?
There's also a preserveConstEnums compiler flag -- how does this interact with these?
There are four different aspects to enums in TypeScript you need to be aware of. First, some definitions:
"lookup object"
If you write this enum:
enum Foo { X, Y }
TypeScript will emit the following object:
var Foo;
(function (Foo) {
Foo[Foo["X"] = 0] = "X";
Foo[Foo["Y"] = 1] = "Y";
})(Foo || (Foo = {}));
I'll refer to this as the lookup object. Its purpose is twofold: to serve as a mapping from strings to numbers, e.g. when writing Foo.X or Foo['X'], and to serve as a mapping from numbers to strings. That reverse mapping is useful for debugging or logging purposes -- you will often have the value 0 or 1 and want to get the corresponding string "X" or "Y".
"declare" or "ambient"
In TypeScript, you can "declare" things that the compiler should know about, but not actually emit code for. This is useful when you have libraries like jQuery that define some object (e.g. $) that you want type information about, but don't need any code created by the compiler. The spec and other documentation refers to declarations made this way as being in an "ambient" context; it is important to note that all declarations in a .d.ts file are "ambient" (either requiring an explicit declare modifier or having it implicitly, depending on the declaration type).
"inlining"
For performance and code size reasons, it's often preferable to have a reference to an enum member replaced by its numeric equivalent when compiled:
enum Foo { X = 4 }
var y = Foo.X; // emits "var y = 4";
The spec calls this substitution, I will call it inlining because it sounds cooler. Sometimes you will not want enum members to be inlined, for example because the enum value might change in a future version of the API.
Enums, how do they work?
Let's break this down by each aspect of an enum. Unfortunately, each of these four sections is going to reference terms from all of the others, so you'll probably need to read this whole thing more than once.
computed vs non-computed (constant)
Enum members can either be computed or not. The spec calls non-computed members constant, but I'll call them non-computed to avoid confusion with const.
A computed enum member is one whose value is not known at compile-time. References to computed members cannot be inlined, of course. Conversely, a non-computed enum member is once whose value is known at compile-time. References to non-computed members are always inlined.
Which enum members are computed and which are non-computed? First, all members of a const enum are constant (i.e. non-computed), as the name implies. For a non-const enum, it depends on whether you're looking at an ambient (declare) enum or a non-ambient enum.
A member of a declare enum (i.e. ambient enum) is constant if and only if it has an initializer. Otherwise, it is computed. Note that in a declare enum, only numeric initializers are allowed. Example:
declare enum Foo {
X, // Computed
Y = 2, // Non-computed
Z, // Computed! Not 3! Careful!
Q = 1 + 1 // Error
}
Finally, members of non-declare non-const enums are always considered to be computed. However, their initializing expressions are reduced down to constants if they're computable at compile-time. This means non-const enum members are never inlined (this behavior changed in TypeScript 1.5, see "Changes in TypeScript" at the bottom)
const vs non-const
const
An enum declaration can have the const modifier. If an enum is const, all references to its members inlined.
const enum Foo { A = 4 }
var x = Foo.A; // emitted as "var x = 4;", always
const enums do not produce a lookup object when compiled. For this reason, it is an error to reference Foo in the above code except as part of a member reference. No Foo object will be present at runtime.
non-const
If an enum declaration does not have the const modifier, references to its members are inlined only if the member is non-computed. A non-const, non-declare enum will produce a lookup object.
declare (ambient) vs non-declare
An important preface is that declare in TypeScript has a very specific meaning: This object exists somewhere else. It's for describing existing objects. Using declare to define objects that don't actually exist can have bad consequences; we'll explore those later.
declare
A declare enum will not emit a lookup object. References to its members are inlined if those members are computed (see above on computed vs non-computed).
It's important to note that other forms of reference to a declare enum are allowed, e.g. this code is not a compile error but will fail at runtime:
// Note: Assume no other file has actually created a Foo var at runtime
declare enum Foo { Bar }
var s = 'Bar';
var b = Foo[s]; // Fails
This error falls under the category of "Don't lie to the compiler". If you don't have an object named Foo at runtime, don't write declare enum Foo!
A declare const enum is not different from a const enum, except in the case of --preserveConstEnums (see below).
non-declare
A non-declare enum produces a lookup object if it is not const. Inlining is described above.
--preserveConstEnums flag
This flag has exactly one effect: non-declare const enums will emit a lookup object. Inlining is not affected. This is useful for debugging.
Common Errors
The most common mistake is to use a declare enum when a regular enum or const enum would be more appropriate. A common form is this:
module MyModule {
// Claiming this enum exists with 'declare', but it doesn't...
export declare enum Lies {
Foo = 0,
Bar = 1
}
var x = Lies.Foo; // Depend on inlining
}
module SomeOtherCode {
// x ends up as 'undefined' at runtime
import x = MyModule.Lies;
// Try to use lookup object, which ought to exist
// runtime error, canot read property 0 of undefined
console.log(x[x.Foo]);
}
Remember the golden rule: Never declare things that don't actually exist. Use const enum if you always want inlining, or enum if you want the lookup object.
Changes in TypeScript
Between TypeScript 1.4 and 1.5, there was a change in the behavior (see https://github.com/Microsoft/TypeScript/issues/2183) to make all members of non-declare non-const enums be treated as computed, even if they're explicitly initialized with a literal. This "unsplit the baby", so to speak, making the inlining behavior more predictable and more cleanly separating the concept of const enum from regular enum. Prior to this change, non-computed members of non-const enums were inlined more aggressively.
There are a few things going on here. Let's go case by case.
enum
enum Cheese { Brie, Cheddar }
First, a plain old enum. When compiled to JavaScript, this will emit a lookup table.
The lookup table looks like this:
var Cheese;
(function (Cheese) {
Cheese[Cheese["Brie"] = 0] = "Brie";
Cheese[Cheese["Cheddar"] = 1] = "Cheddar";
})(Cheese || (Cheese = {}));
Then when you have Cheese.Brie in TypeScript, it emits Cheese.Brie in JavaScript which evaluates to 0. Cheese[0] emits Cheese[0] and actually evaluates to "Brie".
const enum
const enum Bread { Rye, Wheat }
No code is actually emitted for this! Its values are inlined. The following emit the value 0 itself in JavaScript:
Bread.Rye
Bread['Rye']
const enums' inlining might be useful for performance reasons.
But what about Bread[0]? This will error out at runtime and your compiler should catch it. There's no lookup table and the compiler doesn't inline here.
Note that in the above case, the --preserveConstEnums flag will cause Bread to emit a lookup table. Its values will still be inlined though.
declare enum
As with other uses of declare, declare emits no code and expects you to have defined the actual code elsewhere. This emits no lookup table:
declare enum Wine { Red, Wine }
Wine.Red emits Wine.Red in JavaScript, but there won't be any Wine lookup table to reference so it's an error unless you've defined it elsewhere.
declare const enum
This emits no lookup table:
declare const enum Fruit { Apple, Pear }
But it does inline! Fruit.Apple emits 0. But again Fruit[0] will error out at runtime because it's not inlined and there's no lookup table.
I've written this up in this playground. I recommend playing there to understand which TypeScript emits which JavaScript.
I want to know data type using variable name
My final goal is getting a function signature for making a function stub(skeleton code)
but GCC error message just notify only undefined function name
Can I see a symbol table? (for inferencing function signature)
for example, foo.c is like below
#include <stdio.h>
int main() {
int n = 0;
n = foo();
return 0;
}
I want to make a function stub
so I want to know function foo has no parameter and returns an integer value
What should I do?
I think below:
linker error message say function foo is undefined
read line 5
n = foo();
inspect type of n using symbol table
is it right?
sorry for my bad english
please teach me inferencing a function signature
Inject his code into your source file:
typedef struct { int a; char c; } badtype_t;
badtype_t badtype;
then replace the error line like this:
n = badtype; //foo();
or if you want the type foo returns:
badtype = foo();
then you will get some error like this:
incompatible types when initializing type ‘int’ using type ‘badtype_t’
and you can get the type int.
or if you want the type of foo itself:
foo * 2
then you will get some error like this:
invalid operands to binary * (have 'int (*)()' and 'int')
and you can get the type int (*)() (that is, function taking nothing and returning an int).
It seems ok, but this strategy will not be good enough. Using the left-hand side of an expression is not enough to determine the return-type of the function. In particular, there may be no left-hand side at all, simply: foo();. What then?
If you just want to see a symbol table, that's what nm is for.
For example, if you get an error linking foo.o and bar.o together, you can do this:
nm -a foo.o
That will show you all the symbols defined in module foo.
But I don't see why you think this would help. C symbols do not have any type information. There may be enough metadata to distinguish extern linkage, and/or to tell whether a symbol function or data, but that's it. There is no way to tell an int from a float, or a function taking two ints and returning a double from a function taking a char * and returning a different char *.
So, you have some function named foo defined somewhere, and you want to know what its type is.
If you don't actually have a prototype for foo somewhere in your #included header files, this is easy:
If you're using C99, your code is invalid.
Otherwise, foo must take no arguments and return int, or your code is invalid.
And this isn't one of those "technically invalid, but it works on every platform" cases; it will break. For example, with gcc 4.2 for 64-bit x86 linux or Mac, if you do this:
double foo(double f) { return f*2; }
Then, without a header file, call it like this:
double f = foo(2.0);
printf("%f\n", f);
If compiled as C89, this will compile and link just fine (clang or gcc 4.8 will give you a warning; gcc 4.2 won't even do that by default), and run, and print out 2.0. At least on x86_64; on ARM7, you'll corrupt the stack, and segfault if you're lucky. (Of course it actually does double something—either your 2.0 or some random uninitialized value—but it can't return that to you; it's stashed it in an arbitrary floating-point register that the caller doesn't know to access.)
If it is in a header file, you can always search for it. emacs, graphical IDEs, etc. are very good at this. But you can use the compiler to help you out, in two ways.
First, just do this:
gcc -E main.c > main.i
less main.i
Now search for /foo, and you'll find it.
Or you can trick the compiler into giving you an error message, as in perreal's answer.