Recently updated to Marlin 2.0.6.1, because the compiler won't work with 2.0.6 anymore. Updated the platformio as well. Now when I compile I get these errors, mostly multiple defination kinds, before it used to compile with no problems. If anyone know how to fix them I would really appreciate it.
At top level:
C:\users\administrator\.platformio\packages\framework-arduinoststm32-maple\STM32F1\libraries\FreeRTOS701\utility\port.c:285:6: warning: 'prvSetupTimerInterrupt' defined but not used [-Wunused-function]
void prvSetupTimerInterrupt( void )
^~~~~~~~~~~~~~~~~~~~~~
Archiving .pio\build\mks_robin_e3\lib91f\libFreeRTOS701.a
Archiving .pio\build\mks_robin_e3\libe21\libServo.a
Archiving .pio\build\mks_robin_e3\lib6b5\libU8glib-HAL_ID1932#0.4.1.a
Linking .pio\build\mks_robin_e3\firmware.elf
.pio/build/mks_robin_e3/src/src/module/settings.cpp.o: In function `MarlinSettings::datasize()':
C:\users\administrator\.platformio\packages\framework-arduinoststm32-maple\STM32F1\cores\maple/HardwareSerial.h:145: multiple definition of `MarlinSettings::datasize()'
.pio/build/mks_robin_e3/src/src/module/configuration_store.cpp.o:C:\users\administrator\.platformio\packages\framework-arduinoststm32-maple\STM32F1\cores\maple/HardwareSerial.h:145: first defined here
.pio/build/mks_robin_e3/src/src/module/settings.cpp.o: In function `MarlinSettings::postprocess()':
L:\3dPrinter\Marlin-2.0.x/Marlin\src\module/settings.cpp:448: multiple definition of `MarlinSettings::postprocess()'
.pio/build/mks_robin_e3/src/src/module/configuration_store.cpp.o:L:\3dPrinter\Marlin-2.0.x/Marlin\src\module/configuration_store.cpp:422: first defined here
.pio/build/mks_robin_e3/src/src/module/settings.cpp.o: In function `MarlinSettings::size_error(unsigned short)':
L:\3dPrinter\Marlin-2.0.x/Marlin\src\module/settings.cpp:564: multiple definition of `MarlinSettings::size_error(unsigned short)'
.pio/build/mks_robin_e3/src/src/module/configuration_store.cpp.o:L:\3dPrinter\Marlin-2.0.x/Marlin\src\module/configuration_store.cpp:538: first defined here
.pio/build/mks_robin_e3/src/src/module/settings.cpp.o: In function `MarlinSettings::save()':
L:\3dPrinter\Marlin-2.0.x/Marlin\src\module/settings.cpp:575: multiple definition of `MarlinSettings::save()'
.pio/build/mks_robin_e3/src/src/module/configuration_store.cpp.o:L:\3dPrinter\Marlin-2.0.x/Marlin\src\module/configuration_store.cpp:549: first defined here
.pio/build/mks_robin_e3/src/src/module/settings.cpp.o: In function `MarlinSettings::reset()':
L:\3dPrinter\Marlin-2.0.x/Marlin\src\module/settings.cpp:2437: multiple definition of `MarlinSettings::reset()'
.pio/build/mks_robin_e3/src/src/module/configuration_store.cpp.o:L:\3dPrinter\Marlin-2.0.x/Marlin\src\module/configuration_store.cpp:2372: first defined here
.pio/build/mks_robin_e3/src/src/module/settings.cpp.o: In function `say_M569(bool, char const*, bool)':
L:\3dPrinter\Marlin-2.0.x/Marlin\src\module/settings.cpp:2860: multiple definition of `say_M569(bool, char const*, bool)'
.pio/build/mks_robin_e3/src/src/module/configuration_store.cpp.o:L:\3dPrinter\Marlin-2.0.x/Marlin\src\module/configuration_store.cpp:2782: first defined here
.pio/build/mks_robin_e3/src/src/module/settings.cpp.o: In function `MarlinSettings::report(bool)':
L:\3dPrinter\Marlin-2.0.x/Marlin\src\module/settings.cpp:2899: multiple definition of `MarlinSettings::report(bool)'
.pio/build/mks_robin_e3/src/src/module/configuration_store.cpp.o:L:\3dPrinter\Marlin-2.0.x/Marlin\src\module/configuration_store.cpp:2821: first defined here
.pio/build/mks_robin_e3/src/src/module/settings.cpp.o: In function `MarlinSettings::_load()':
L:\3dPrinter\Marlin-2.0.x/Marlin\src\module/settings.cpp:1424: multiple definition of `MarlinSettings::_load()'
.pio/build/mks_robin_e3/src/src/module/configuration_store.cpp.o:L:\3dPrinter\Marlin-2.0.x/Marlin\src\module/configuration_store.cpp:1377: first defined here
.pio/build/mks_robin_e3/src/src/module/settings.cpp.o: In function `MarlinSettings::validate()':
L:\3dPrinter\Marlin-2.0.x/Marlin\src\module/settings.cpp:2303: multiple definition of `MarlinSettings::validate()'
.pio/build/mks_robin_e3/src/src/module/configuration_store.cpp.o:L:\3dPrinter\Marlin-2.0.x/Marlin\src\module/configuration_store.cpp:2238: first defined here
.pio/build/mks_robin_e3/src/src/module/settings.cpp.o: In function `MarlinSettings::load()':
L:\3dPrinter\Marlin-2.0.x/Marlin\src\module/settings.cpp:2317: multiple definition of `MarlinSettings::load()'
.pio/build/mks_robin_e3/src/src/module/configuration_store.cpp.o:L:\3dPrinter\Marlin-2.0.x/Marlin\src\module/configuration_store.cpp:2252: first defined here
.pio/build/mks_robin_e3/src/src/module/settings.cpp.o:(.bss._ZN14MarlinSettings10validatingE+0x0): multiple definition of `MarlinSettings::validating'
.pio/build/mks_robin_e3/src/src/module/configuration_store.cpp.o:(.bss._ZN14MarlinSettings10validatingE+0x0): first defined here
.pio/build/mks_robin_e3/src/src/module/settings.cpp.o:(.bss._ZN14MarlinSettings12eeprom_errorE+0x0): multiple definition of `MarlinSettings::eeprom_error'
.pio/build/mks_robin_e3/src/src/module/configuration_store.cpp.o:(.bss._ZN14MarlinSettings12eeprom_errorE+0x0): first defined here
.pio/build/mks_robin_e3/src/src/module/settings.cpp.o:L:\3dPrinter\Marlin-2.0.x/Marlin\src\module/settings.cpp:445: multiple definition of `new_z_fade_height'
.pio/build/mks_robin_e3/src/src/module/configuration_store.cpp.o:L:\3dPrinter\Marlin-2.0.x/Marlin\src\module/configuration_store.cpp:419: first defined here.pio/build/mks_robin_e3/src/src/module/settings.cpp.o:(.bss.settings+0x0): multiple definition of `settings'
.pio/build/mks_robin_e3/src/src/module/configuration_store.cpp.o:(.bss.settings+0x0): first defined here
Related
I'm reading the source code of the main json11 header file.
It contains the following declaration:
template <class T, class = decltype(&T::to_json)>
Json(const T & t) : Json(t.to_json()) {}
I'm trying to find some documentation about this usage of decltype and class inside a template declaration but no success.
Does this construction/usage has a name in C++? Any good reference about it?
It's using SFINAE ("Substitution Failure Is Not An Error"), a common technique for advanced template stuff. In this case, it's used as a crude(1) test whether the type T has a function named to_json.
How it works: if the expression T::to_json is well-formed (there is something named to_json inside the type T), decltype(T::to_json) denotes a valid type and the constructor template can be used normally.
However, if T::to_json is ill-formed (i.e. if there is no to_json member inside T), it means substituting the template argument for T has failed. Per SFINAE, this is not an error of the entire program; it just means that the template is removed from further consideration (as if it was never part of the class).
The effect is thus that if type T has a member to_json, you can use an object of type T to initialise a Json object. If there is no such member in T, the constructor will not exist.
(1) I'm saying crude test because this only checks that T has such a member. It doesn't check that the member is a function which can be invoked without arguments and returns something another constructor of Json can accept. A tighter-fitting test might look something like this:
template <class T, class = std::enable_if_t<std::is_constructible<Json, decltype(std::declval<const T>().to_json())>::value>>
Json(const T & t) : Json(t.to_json()) {}
[Live example]
Context:
I'm trying to learn smart pointers and I came across a case I don't understand.
I'm creating an unordered_map of unique_ptr<list<int>>. Declared as following:
unique_ptr<unordered_map<uint32_t, unique_ptr<list<uint32_t>>>> mymap;
The map and its contents are private data of a class and I want them to be destroyed when the class is destroyed. Therefore I use a unique_ptr for the map and for each list.
Problem:
When I call emplace, like so:
mymap->emplace(index, make_unique<list<uint32_t>>());
My program compiles just fine. It also works when I call insert creating pair explicitly:
mymap->insert(std::make_pair(index, std::make_unique<std::list<uint32_t>>()));
However, the following line:
mymap->insert({index, make_unique<std::list<uint32_t>>()});
produces the following errors (GCC in Linux Ubuntu)):
/usr/include/c++/5/ext/new_allocator.h:120:4: error: use of deleted function ‘constexpr std::pair<_T1, _T2>::pair(const std::pair<_T1, _T2>&) [with _T1 = const unsigned int; _T2 = std::unique_ptr >]’
{ ::new((void *)__p) _Up(std::forward<_Args>(__args)...); }
From the this answer I learned that the difference between the two methods is that insert copies or moves a key-value pair into the container, while emplace builds it in place. So perhaps the problem is that I'm not properly using the unique_ptr?
Question: Why the first two calls succeed while the third fails?
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.
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.
Consider the following code:
int main (void) {
int i = xyzzy();
return i;
}
int xyzzy (void) {
return 42;
}
Now, although the prototype for xyyzy is unkown at the point of use, this works in c89 mode because the default return type of a function that has no prototype is int so the implicit function prototype and actual function are compatible.
And, in fact, if you change the return type of the function to float, you get (as expected):
testprog.c:6: error: conflicting types for 'xyzzy'
testprog.c:2: error: previous implicit declaration of 'xyzzy' was here
because the implicit prototype and actual function no longer match.
The original code compiled with gcc --std=c89 --pedantic -Wall -Wextra only gives me the warning:
testprog.c: In function 'main':
testprog.c:2: warning: implicit declaration of function 'xyzzy'
which is expected, because c89 has this to say in 3.7.1 Function definitions:
extern int max(int a, int b) { ... }: Here extern is the storage-class specifier and int is the type specifier (each of which may be omitted as those are the defaults).
and in 3.3.2.2 Function calls:
If the expression that precedes the parenthesized argument list in a function call consists solely of an identifier, and if no declaration is visible for this identifier, the identifier is implicitly declared exactly as if, in the innermost block containing
the function call, the declaration extern int identifier(); appeared.
So the use of a function before declaring it definitely results in the default prototype being created.
However, both those phrases have been removed in c99 and we instead find in 6.5.2.2 Function calls (my bold):
If the expression that denotes the called function has type pointer to function returning an object type, the function call expression has the same type as that object type, and has the value determined as specified in 6.8.6.4. Otherwise, the function call has type void.
I understand it to mean that, if there's no declaration in view when you try to call a function, it's implicitly declared with a void return type.
Yet, when compiling with gcc --std=c99 --pedantic -Wall -Wextra, I get just the same warning about the implicit declaration.
Shouldn't c99 have declared that function implicitly as returning void? If it had, I would have expected a previous implicit declaration error similar to the one I got when I tried to redeclare it as returning float.
Is gcc broken here, or am I missing something in the standard?
You are reading the standard incorrectly. There's no such thing as implicit function declaration in C. It is removed from the language by C99.
GCC issues a warning when it sees an erroneous construct that looks like an implicit function declaration. This is OK as far as the standard is concerned. The standard requires a diagnostic here, and a warning is a diagnostic. You may use -Werror=implicit-function-declaration flag to GCC to turn this into an error.
This is covered in a note to 6.5.1 Primary expressions:
2 - An identifier is a primary expression, provided it has been declared as designating an
object (in which case it is an lvalue) or a function (in which case it is a function
designator). 79)
79) Thus, an undeclared identifier is a violation of the syntax.
A conforming implementation is required by 5.1.1.3 Diagnostics to produce a diagnostic message in response to the syntax violation of a function call expression involving an undeclared identifier as the expression denoting the called function. It is of course free to proceed to compile the program as if the identifier had been declared in the implicit-int C89 style.
The paragraph 6.5.2.2p5 must be read with reference to the constraint 6.5.2.2p1:
1 - The expression that denotes the called function shall have type pointer to function
returning void or returning an object type other than an array type.
So, if the "expression that denotes the called function" does not have type "pointer to function returning an object type", it must ipso facto (by the constraint 6.5.2.2p1) have type "pointer to function returning void", and it is this case which the "Otherwise" in 6.5.2.2p5 covers. That is, with my insertion in [square brackets]:
5 - If the expression that denotes the called function has type pointer to function returning an object type, the function call expression has the same type as that object type, and has the value determined as specified in 6.8.6.4. Otherwise, [i.e. if the expression that denotes the called function has type pointer to function returning void,] the function call has type void.
This is a case of special language being required for void as opposed to object types; is not a licence for the called function expression to be or contain an undeclared identifier.