I started learning C++ from a great tutorial available at https://learnxinyminutes.com/docs/c++/ and would like to analyze in Frama-C a simplest example that shows references:
using namespace std;
#include <iostream>
#include <string>
int main() {
string foo = "I am foo";
string bar = "I am bar";
string& fooRef = foo; // This creates a reference to foo.
fooRef += ". Hi!"; // Modifies foo through the reference
cout << fooRef; // Prints "I am foo. Hi!"
// Doesn't reassign "fooRef". This is the same as "foo = bar", and
// foo == "I am bar"
// after this line.
cout << &fooRef << endl; //Prints the address of foo
fooRef = bar;
cout << &fooRef << endl; //Still prints the address of foo
cout << fooRef; // Prints "I am bar"
//The address of fooRef remains the same, i.e. it is still referring to foo.
return 0;
}
I compiled and installed Frama-C C++ plug-in called "Frama-Clang".
Now when I run frama-c I get warnings and errors in the output:
$ frama-c refs.cc
[kernel] Parsing FRAMAC_SHARE/libc/__fc_builtin_for_normalization.i (no preprocessing)
[kernel] Parsing refs.cc (external front-end)
refs.cc:13:17: warning: using directive refers to implicitly-defined namespace 'std'
using namespace std;
^
In file included from refs.cc:14:
In file included from /usr/share/frama-c/frama-clang/libc++/iostream:29:
/usr/share/frama-c/frama-clang/libc++/ostream:31:40: error: implicit instantiation of undefined template 'std::basic_ios<char, std::char_traits<char> >'
class basic_ostream : virtual public basic_ios<charT,traits> {
^
refs.cc:23:7: note: in instantiation of template class 'std::basic_ostream<char, std::char_traits<char> >' requested here
cout << fooRef; // Prints "I am foo. Hi!"
^
/usr/share/frama-c/frama-clang/libc++/iosfwd:37:68: note: template is declared here
template <class charT, class traits = char_traits<charT> > class basic_ios;
^
code generation aborted due to one compilation error
[kernel] user error: Failed to parse C++ file. See Clang messages for more information
[kernel] user error: stopping on file "refs.cc" that has errors.
[kernel] Frama-C aborted: invalid user input.
What is wrong?
(Frama-C is installed from a debian-testing repository in version 20170501+phosphorus+dfsg-2)
First of all, I'd like to point out the caveat on the Frama-Clang page:
Frama-Clang is currently in an early stage of development. It is known to be incomplete and comes without any bug-freeness guarantee.
Thus, if you're not already familiar with C++, I'd kindly suggest that starting right away with Frama-Clang might be a pretty big effort.
That said, the issue is, as mentioned in the comments, that STL support in Frama-Clang is minimal (in particular, the innocent-looking iostream is not exactly the easiest piece of code to handle when it comes to templates).
You might have better luck by using frama-c -cxx-nostdinc refs.cc, which will use your system's standard library instead of the one shipped with Frama-Clang: this will at least let clang type-check your code. There is however absolutely no guarantee that Frama-Clang itself will be able to understand all the constructions provided by this library.
Related
In an old project code was a statement like:
cout.operator<<("Hi...");
ostream.operator<<("Hi....");
It argued that it can be written as followa, resulting in same output:
cout << "Hi..";
I have tried to put these statement in main(). But compiler gives error:
In function 'int main()':
11:3: error: 'ostream' was not declared in this scope
11:3: note: suggested alternative:
In file included from /usr/include/c++/4.9/ios:38:0,
from /usr/include/c++/4.9/ostream:38,
from /usr/include/c++/4.9/iostream:39,
from 2:
/usr/include/c++/4.9/iosfwd:136:33: note: 'std::ostream'
typedef basic_ostream<char> ostream;
The other thing that I am not convinced of is this statement that ostream can directly call operator<<. Same about cout that can it call operator<< directly.
If some body could elaborate or explain how, then I will able to debug the code.
Thanks.
The code line in question can actually ber compiled and does work, e.g:
#include <iostream>
using namespace std;
int main (void)
{
cout << "Hi"; // code line in question
cout << endl;
return 0;
}
The quoted error is caused by using ostream, which is the type of cout, in a place where an object (not a type) is required.
As also mentioned in a comment, the fix of that error is using an object of that type instead. Which basically means the first line of quoted code, i.e. the line in the solution code above.
I am currently trying to get the following very simple boost::phoenix::lambda to compile:
#include <iostream>
#include <boost/phoenix/scope.hpp>
int main() {
boost::phoenix::lambda[std::cout << "Lambda!!"]();
}
However, this generates a host of errors (too much to post here), none which make any sense to me. Here is an excerpt of the compiler output:
error: 'std::ios_base::ios_base(const std::ios_base&)' is private
within this context
error: initializer for
'boost::proto::exprns_::basic_expr<boost::proto::tagns_::tag::terminal,
boost::proto::argsns_::term<boost::phoenix::vector0<> >, 0l>::proto_child0
{aka boost::phoenix::vector0<>}' must be brace-enclosed
I am compiling these using MinGW 4.7.2 on Windows XP with Boost 1.53.0. What am I doing wrong?
Firstly, always
#include <boost/phoenix/phoenix.hpp>
unless you know what you're doing.
Secondly, you need to make either operand of operator<< be a phoenix terminal, otherwise, it will be just
std::cout << "Lambda!!"
which is an expression of type std::ostream&...
Now, you could do anything, really, e.g.
phx::ref(std::cout) << "Lambda!!"
or
std::cout << phx::val("Lambda!!")
Either will compile.
I've just encountered an problem today: The following code seems to work in MSVC++ 2010 but not with Clang LLVM 4.1 (with GNU++11).
#include <fstream>
void foo(std::fstream& file){
file << "foo";
}
int main() {
std::fstream dummy("dummy");
foo(dummy);
return 0;
}
generates
Invalid operands to binary expression (std::fstream (aka basic_fstream<char>) and const char[4])
on Clang. I thought passing iostream arguments by reference would be common practice in C++. I'm not even sure if this is related to clang, C++11 or anything else.
Any idea how I can pass streams to functions then?
I assume that your original code (that you only partially posted in your original question) looked something like this:
#include <iosfwd>
void foo(std::fstream& file){
file << "foo";
}
int main() {
std::fstream dummy("dummy");
foo(dummy);
return 0;
}
Indeed, this gives the following error message with clang++ 3.2
Compilation finished with errors:
source.cpp:4:10: error: invalid operands to binary expression ('std::fstream' (aka 'basic_fstream<char>') and 'const char [4]')
file << "foo";
~~~~ ^ ~~~~~
source.cpp:8:17: error: implicit instantiation of undefined template 'std::basic_fstream<char, std::char_traits<char> >'
std::fstream dummy("dummy");
^
/usr/lib/gcc/x86_64-linux-gnu/4.7/../../../../include/c++/4.7/iosfwd:118:11: note: template is declared here
class basic_fstream;
^
2 errors generated.
Unfortunately, you only posted the first error message but not the second.
From the second error message, it is obvious that you only #include <iosfwd> but not #include <fstream>. If you fix that, everything will be OK.
Please post both the complete code and all the error messages next time.
This compiles with out problems in VS 2009? Am I stupid?
GCC gives a warning, that the template is private....?
What am I missing?
#include <iostream>
using namespace std;
class A
{
private:
template<typename T>
A& operator<<(const T & v)
{
cout << v << endl;
return *this;
}
};
int main()
{
A a;
a << 4;
system("pause");
}
Microsoft acknowledges the bug and claims it will be fixed in the next major release for the compiler (which I read as VC11/VS-whatever-is-after-2010 - probably not a service pack for VC10/VS2010):
http://connect.microsoft.com/VisualStudio/feedback/details/649496/visual-c-doesnt-respect-the-access-modifier-for-operator-member-function-templates
from the comments, the fix appears to be already made to an internal compiler build.
This code should not compile - this is a bug (or silly extension) in VS. GCC should refuse it as well. The operator is inaccessible in the scope it is used.
Comeau treats this correctly:
"ComeauTest.c", line 28: error: function "A::operator<<(const T &) [with T=int]"
(declared at line 14) is inaccessible
a << 4;
EDIT: A relevant standard snippet, from 13.3/1
[Note: the function selected by
overload resolution is not guaranteed
to be appropriate for the context.
Other restrictions, such as the
accessibility of the function, can
make its use in the calling context
ill-formed. ]
No, you're not stupid - it's broken code and should be rejected. The Comeau compiler (http://www.comeaucomputing.com/tryitout) does correctly reject it.
FC++ is a library for functional programming in C++. I am using it on MinGW with gcc 4.5.0. When I use the more basic features, I have no problems. But one of the more advanced features is giving me a template-related error (or maybe there's just a problem with my code...couldn't be!).
Does anybody have FC++ working with 4.5.0? See anything wrong with my code?
The link text is solidly out of date, though it shows a history of issues with gcc and template specialization. The link text isn't more up to date.
Here's my code:
#include <iostream>
#include "prelude.h"
using namespace fcpp;
using namespace std;
struct TwoTimes {
template <class T>
struct Sig : public FunType<T,T> {};
template <class F>
F operator() (const F& x) const { return 2*x; };
} twoTimes;
int main(int argc, char* argv[] )
{
cout << compose(twoTimes,twoTimes)(3) << endl;
return 0;
}
The error I get is:
In file included from full.h:14:0,
from lambda.h:38,
from operator.h:29,
from function.h:23,
from reuse.h:14,
from list.h:31,
from prelude.h:32,
from y.cxx:2:
smart.h: In instantiation of 'fcpp::FunctoidTraits<TwoTimes>':
prelude.h:142:74: instantiated from 'fcpp::impl::XCompose::Sig<TwoTimes, TwoTimes>'
full.h:94:53: instantiated from 'fcpp::Full2<fcpp::impl::XCompose>::Sig<TwoTimes, TwoTimes>'
y.cxx:18:46: instantiated from here
smart.h:103:7: error: no type named 'Type' in 'struct
fcpp::impl::NeededASmartFunctoidButInsteadGot<TwoTimes, false>'
In file included from y.cxx:2:0:
prelude.h: In instantiation of 'fcpp::impl::XCompose::Sig<TwoTimes, TwoTimes>':
full.h:94:53: instantiated from 'fcpp::Full2<fcpp::impl::XCompose>::Sig<TwoTimes, TwoTimes>'
y.cxx:18:46: instantiated from here
prelude.h:142:74: error: 'fcpp::FunctoidTraits<TwoTimes>::max_args' is not a valid
template argument for type 'int' because it is a non-constant expression
In file included from lambda.h:38:0,
from operator.h:29,
from function.h:23,
from reuse.h:14,
from list.h:31,
from prelude.h:32,
from y.cxx:2:
full.h: In instantiation of 'fcpp::Full2<fcpp::impl::XCompose>::Sig<TwoTimes, TwoTimes>':
y.cxx:18:46:
instantiated from here
full.h:94:53: error: no type named 'Arg1Type' in 'struct
fcpp::impl::XCompose::Sig<TwoTimes, TwoTimes>'
y.cxx: In function 'int main(int, char**)':
y.cxx:18:46: error: no match for call to '(fcpp::Compose) (TwoTimes&, TwoTimes&)'
Well .... the links you refer to are seven years old. In dog and compiler years, that is a good lifetime.
If you want functional programming with (current) C++ compilers, maybe some of the Boost libraries may be of interest?
If the answer is still needed to this, the struct TwoTimes needs to be wrapped to work with FC++. I have worked a lot with FC++ over several years. The best thing I can do is point to here on the C2 wiki where I have discussed this:
http://c2.com/cgi/wiki?FunctoidsInCpp
Any posting there I will see.