Consider this example:
int main()
{
int a = 100;
std::cout<<[=,&a](int a,int b){return a+b;}(99,1);
return 0;
}
The output is 101 instead of my expectation of 100.
I cant specify as so [&a,=] as it gives error.
How do i avoid the name hiding and refer to the parameter. i know changing the name is the option but i'm curious. also reference to standard will be helpful
EDIT:
i'm using gcc 4.7.1
EDIT:
here is the ideone link showing the demo. i used c++ 4.7.2 complier there
ideone
I could not find anything related to lambdas in the standard that would indicate your results are the expected behavior. I agree with Andy's comment that this is a bug in GCC. GCC 4.7.2 on Linux, GCC 4.7.2 from MinGW, and GCC 4.8.0 from MinGW produce the same results as in the question but VC++10 and VC++11 produce the expected results.
You should consider filing a bug report
Since the parameter doesn't have a scope that you can name, you can't use scope resolution operator to disambiguate, nor this or any other such means. Therefore, it's impossible to disambiguate this scenario the way you want. You'll just have to not give your variables horrible and clashing names.
How do I print out the outer a here, but in the inner scope?
int a = 1;
{
int a = 2;
cout << a << endl;
}
You either change the name of one of the variables - or you don't.
The same goes for your lambda.
(I apologize that I can't reference the standard like you requested - I don't have it.)
Related
I ran across a compile error in clang with this code. I don't see any problem with it and it works in msvc and gcc. Am I missing something or is it a clang bug?
#include <iostream>
#include <string>
#include <type_traits>
constexpr bool do_tests()
{
// prints error message at runtime if test is false
auto verify = [](bool test, std::string message = "error") {
if (!std::is_constant_evaluated() && !test)
std::cout << message << '\n';
return test;
};
return verify(1 == 1, "test");
};
int main()
{
constexpr bool b = do_tests();
std::cout << b << '\n';
}
compiler explorer
Inexplicable error message from clang:
basic_string.h:356:10: note: assignment to member '_M_local_buf' of union with no active member is not allowed in a constant expression
There is no problem with the code and Clang also compiles it correctly if you use libc++ (-stdlib=libc++). Compiler explorer by default uses libstdc++ for Clang (-stdlib=libstdc++). There simply seems to be a compatibility issue between the two. My guess is that libstdc++ is implementing the constexpr string in a way that is technically not allowed in constant expressions, but GCC tends to be less strict in that regard than Clang is, so that Clang fails with the implementation while GCC doesn't have a problem with it.
To be more precise in libstdc++ the implementation of std::string contains an anonymous union with one member being a _CharT array named _M_local_buf. Then libstdc++ is doing the following if the evaluation happens in a constant expression evaluation (from https://github.com/gcc-mirror/gcc/blob/master/libstdc%2B%2B-v3/include/bits/basic_string.h#L355)
for (_CharT& __c : _M_local_buf)
__c = _CharT();
in order to set the union member _M_local_buf to active and zero it.
The problem is that prior to this loop no member of the union has been set to active and setting a member (subobject) through a reference, rather than directly by name or through member access expressions, is technically not specified in the standard to set a member to active. As a consequence that technically has undefined behavior, which is why Clang (correctly) doesn't want to accept it as constant expression. If the member was set as active beforehand, e.g. with an extra line _M_local_buf[0] = _CharT(); it would be fine.
Now of course it seems a bit silly that setting _M_local_buf[0] directly is fine, but setting it through a reference __c isn't, which is probably why GCC still accepts that as a constant expression and I guess there is probably a CWG issue about this.
There is a libstdc++ bug report relating to a very similar issue here, but that is already supposed to be fixed for a while.
It seems that the commit https://github.com/gcc-mirror/gcc/commit/98a0d72a610a87e8e383d366e50253ddcc9a51dd has (re-)introduced the particular issue you are seeing here. Before the commit the member was set active correctly. Might be worth it to open an issue about this, although as mentioned above Clang is being very pedantic here and as the linked bug report also says, the standard should probably be changed to allow this.
My doubt is that does "auto" keyword works in C++4.3.2? I was writing a program to check the presence of a prefix in a word, I wrote something like this --
auto res = mismatch(prefix,word);
And when I compiled it gave the error--
res was not declared in scope
What should I use in place of "auto" in case if "auto" is not available in c++4.3.2.
Here u can see my full code-- http://paste.ubuntu.com/9351873/
#Surayans Tiwari
Return type of mismatch() is std::pair. Please refer following page and correct your usage.
http://en.cppreference.com/w/cpp/algorithm/mismatch
I have the same opinion with #KeithThompson that you are talking about using GCC 4.3.2 instead of using C++ 4.3.2.
Assume that I perceive correctly, the compilation error that you got is due to the auto type is not supported in GCC 4.3.2 yet.
According to the C++11 support in GCC reference,
https://gcc.gnu.org/projects/cxx0x.html
the auto-typed variables is supported since GCC 4.4.
If you wish to try the feature of auto type, you should use a newer GCC compiler.
I understand that local variables are not initialised automatically in C++, so before using them, you should always assign a value to them. However, at least in simple cases, the compiler should warn you in case you forget it. I'm more or less relying on and referring to this article.
Given this program, I'd assume to get a warning when sending x to std::cout...
#include <iostream>
int main(int argc, const char * argv[])
{
int x;
std::cout << x;
return 0;
}
...but no warning pops up. If, however, I run the static analyzer, I do get the expected warning: Function call argument is an uninitialized value.
I compile & run using Xcode 5.1 with the Apple LLVM 5.1 compiler. I use the standard build settings from Xcode's command line project template (C++), the language dialects are set to GNU99 (for C) and GNU++11 (C++).
The Uninitialized Variables option is set to Yes (Aggressive) (-Wconditional-uninitialized). Switching to just Yes (-Wuninitialized) raises the warning: Variable 'x' is uninitialized when used here. Question Part 1: Why does the warning not show with the default setting (-Wconditional-uninitialized)? The documentation in Xcode suggests that the aggressive option finds more issues:
You can toggle between the normal uninitialized value checking or the more aggressive (conservative) checking which finds more issues but the checking is much stricter.
Strangely enough, when I run the program, the value is always set to 0, so for some reason, it seems to be initialised. Question Part 2: Why is that?
Why not the warning?
Using clang with -Wall on my system correctly warns about the error. Apparently, the default settings do not include -Wall (may be to avoid generating warnings with correct code that was written before some of the warnings were introduced).
In general, you're however going to be in trouble if you rely on the compiler to help you with sloppy programming. Typing in code without thinking carefully and hoping the compiler will tell you all mistakes is bad in any language but a true total disaster with C++. The main philosophy of C++ is simply that the programmer doesn't make any error, so just don't make them ;-)
Think carefully and also always work with -Wall if you can.
Why is initialized?
Apparently, you've not understood what is the meaning of "undefined behavior". It doesn't mean the program crashes, it doesn't mean it will do anything funny. It means it can do anything and normally the programs do whatever will create the most problems for you in the future.
Often this most dangerous behavior is to make it look as if everything is fine (e.g. that your variable is indeed initialized). The bad values will only show once you put that code in production or only when you show your program running in front of a vast audience. At that point, the value will be different and the video of your public crash will go viral on youtube, your wife will change the door locks and even your parents will not answer your phone calls.
Just initialize your variables; it's better :-)
It's necessary but enough to turn on -Wall to make our code safe.
e.g. The following code, under MacOS's g++(it's clang) will print out 0, but it is definitely a UB:
#include <stdio.h>
#include <iostream>
using namespace std;
class Blob {
public:
int age;
void hello() { printf("hello\n"); }
};
int main() {
Blob a;
//a.hello();
cout << a.age << endl;
return 0;
}
Ok so I was messing around on Ideone and accidentally submitted this piece of code, however to my surprise it actually compiled and ran outputting a value of 0, here.
#include <iostream>
using namespace std;
const int five( )
{
const int i = 5;
}
int main() {
cout << five( ) << endl;
return 0;
}
I then tried this in Visual Studio, and on Codepad however both failed to compile because five() does not return a value, as one would expect. My question, is of course, why does this compile fine on Ideone even though the code, to my understanding is wrong and shouldn't compile.
Plain and simply (from C++11 6.6.3 "The return statement"):
Flowing off the end of a function is equivalent to a return with no value; this results in undefined behavior in a value-returning function.
So the compiler is pretty much allowed to do whatever it wants. Clearly, a diagnostic is something I'd prefer from a compiler, but there are times when it can be difficult to diagnose (like when the return is inside conditional logic, and the 'end' of the function would never be reached).
Note that I get the following warning with GCC 4.6.1 (using the Wall option):
test.cpp:8:1: warning: no return statement in function returning non-void [-Wreturn-type]
I'm not sure what options ideone passes to GCC (I imagine that -Wall would do the same with the 4.3.4 version that ideone uses).
Some related information:
In C it's OK for a function that is declared to return a value to not actually do so in certain circumstances; in C it only results in undefined behavior if the function's return value is actually used. Pre-standard C didn't always support the void type, so functions that didn't return anything were often declared to return int, explicitly or implicitly. From C99 6.9.1/12 "Function definitions": If the } that terminates a function is reached, and the value of the function call is used by the caller, the behavior is undefined.
Also, as mentioned in a couple comments, flowing off the end of main() is treated specially by C++ and C99 and later.
Not returning a value from a non-void function is a mistake, but not all compiler treats it as an error -- for example, GCC only emits a warning when it encounters this. Other compilers may be paranoid (and they're right) and don't let you compile such code. Of course compiler behavior may be modified using different switches and options.
The return value of 0 is just a random value -- it might equally be 255, -1 or any other garbage, as doing this is undefined behavior (except for main, for which C99 specifies that an implicit 0 return value should be assumed).
It appears that ideone doesn't display warnings, it only displays the compiler output if there was an error. On the version of GCC that ideone is using (gcc 4.3) this isn't an error, it's just a warning.
The code has undefined behavior. Even though what you're doing is wrong, the compiler is not required to diagnose it. The other point is that ideone uses what is now a fairly old version of gcc. A reasonably current version of gcc (e.g., 4.7) will at least give you a warning that your function is declared to return a value, but doesn't -- but not by default. You have to turn it on with something like -Wall to get the warning (but as a general rule, I'd always use at least -Wall with gcc).
I am using g++ on Ubuntu 10.10(64-bit) if the OS is at all relevant for the matter.
I saw something strange so i decided to check and for some reason this code
#include <iostream>
int main()
{
int a;
std::cout << a << std::endl;
return 0;
}
always prints 0. Obviously g++ does auto initialization of uninitialized variables to their corresponding null-value. The thing is I want to turn that feature off, or at least make g++ show warning about using uninitialized variables, since this way my code won't work well when compiled on VS for instance. Besides I'm pretty sure the C++ standard states that a variable which isn't implicitly initialized with some value has an undefined value amongst all it's possible values, which should in fact be different with every execution of the program, since different parts of the operating memory are used every time it's executed.
Explicit question: Is there a way to make g++ show warnings for uninitialized variables?
GCC does not initialize uninitialized variables to 0. It's just a case that a is 0.
If what you want to do is to receive warnings when you use uninitialized variables you could use GCC option -Wuninitialized (also included by -Wall).
However it can't statically spot any possible usage of uninitialized variables: you'll need some run time tools to spot that, and there's valgrind for this.
You might also try to use a tool like cppcheck. In general, in well written C++ there is rarely a reason to declare a variable without initializing it.