My colleagues and I had a strange bug in a C++ Builder program and boiled it down to the following snippet:
#include <vcl.h>
#include <iostream>
void SIDE_EFFECTS() {
if (StrToFloat("1337")) {
throw "abc";
}
}
int _tmain(int argc, _TCHAR* argv[])
{
double innocent = StrToFloat("42");
std::cout << innocent << std::endl;
try {
SIDE_EFFECTS();
} catch (...) {
}
std::cout << innocent << std::endl;
return 0;
}
Expected Output:
42
42
Actual Output when compiled for 64bit/ReleaseBuild/OptimizationsON:
42
1337
Compiler (latest 10.1 Berlin version of C++ Builder):
Embarcadero C++ 7.20 for Win64 Copyright (c) 2012-2016 Embarcadero Technologies, Inc.
Embarcadero Technologies Inc. bcc64 version 3.3.1 (35759.1709ea1.58602a0) (based on LLVM 3.3.1)
The internet says [citation needed] that the bug is always in the user program but never in the compiler or standard library, so please enlighten us if/where we do things that are not to be done in C++ / C++ Builder.
Strictly speaking, there is nothing wrong with this code, so it has to be a compiler bug. File a bug report at Quality Portal.
That being said, you should generally stay away from using catch (...). If you are going to catch an exception at all, at least catch what you are expecting and willing to handle:
catch (const char *)
Let anything unexpected pass through and be handled higher up the caller chain.
I would not recommend throwing a string literal directly. It is better to wrap it in a std::runtime_error or System::Sysutils::Exception based object instead.
#include <vcl.h>
#include <iostream>
#include <stdexcept>
void SIDE_EFFECTS() {
if (StrToFloat("1337")) {
throw std::runtime_error("abc");
}
}
int _tmain(int argc, _TCHAR* argv[])
{
double innocent = StrToFloat("42");
std::cout << innocent << std::endl;
try {
SIDE_EFFECTS();
} catch (const std::runtime_error &) {
}
std::cout << innocent << std::endl;
return 0;
}
#include <vcl.h>
#include <iostream>
void SIDE_EFFECTS() {
if (StrToFloat("1337")) {
throw Exception("abc");
}
}
int _tmain(int argc, _TCHAR* argv[])
{
double innocent = StrToFloat("42");
std::cout << innocent << std::endl;
try {
SIDE_EFFECTS();
} catch (const Exception &) {
}
std::cout << innocent << std::endl;
return 0;
}
Related
I am using code that runs on ARM (not Intel processor). Running c++11 code example (CODE A) from: http://www.cplusplus.com/reference/condition_variable/condition_variable/wait_for/ to test the wait_for() mechanism. This is not working right - looks like the wait_for() does not wait. In Intel works fine. After some research and using pthread library directly and setting MONOTONIC_CLOCK definition, solves the issue (CODE B).
(Running on ARM is not the issue)
My problem is :
How can I force the C++11 API wait_for() to work with MONOTONIC_CLOCK?
Actually I would like to stay with 'CODE A' but with the support or setting of MONOTONIC_CLOCK.
Thanks
CODE A
// condition_variable::wait_for example
#include <iostream> // std::cout
#include <thread> // std::thread
#include <chrono> // std::chrono::seconds
#include <mutex> // std::mutex, std::unique_lock
#include <condition_variable> // std::condition_variable, std::cv_status
std::condition_variable cv;
int value;
void read_value() {
std::cin >> value;
cv.notify_one();
}
int main ()
{
std::cout << "Please, enter an integer (I'll be printing dots): \n";
std::thread th (read_value);
std::mutex mtx;
std::unique_lock<std::mutex> lck(mtx);
while
(cv.wait_for(lck,std::chrono::seconds(1))==std::cv_status::timeout)
{
std::cout << '.' << std::endl;
}
std::cout << "You entered: " << value << '\n';
th.join();
return 0;
}
CODE B
#include <sys/time.h>
#include <unistd.h>
#include <iostream> // std::cout
#include <thread> // std::thread
#include <chrono> // std::chrono::seconds
#include <mutex> // std::mutex, std::unique_lock
#include <condition_variable> // std::condition_variable, std::cv_status
const size_t NUMTHREADS = 1;
pthread_mutex_t mutex;
pthread_cond_t cond;
int value;
bool done = false;
void* read_value( void* id )
{
const int myid = (long)id; // force the pointer to be a 64bit integer
std::cin >> value;
done = true;
printf( "[thread %d] done is now %d. Signalling cond.\n", myid, done
);
pthread_cond_signal( &cond );
}
int main ()
{
struct timeval now;
pthread_mutexattr_t Attr;
pthread_mutexattr_init(&Attr);
pthread_mutexattr_settype(&Attr, PTHREAD_MUTEX_RECURSIVE);
pthread_mutex_init(&mutex, &Attr);
pthread_condattr_t CaAttr;
pthread_condattr_init(&CaAttr);
pthread_condattr_setclock(&CaAttr, CLOCK_MONOTONIC);
pthread_cond_init(&cond, &CaAttr);
std::cout << "Please, enter an integer:\n";
pthread_t threads[NUMTHREADS];
int t = 0;
pthread_create( &threads[t], NULL, read_value, (void*)(long)t );
struct timespec ts;
pthread_mutex_lock( &mutex );
int rt = 0;
while( !done )
{
clock_gettime(CLOCK_MONOTONIC, &ts);
ts.tv_sec += 1;
rt = pthread_cond_timedwait( & cond, & mutex, &ts );
std::cout << "..." << std::endl;
}
pthread_mutex_unlock( & mutex );
std::cout << "You entered: " << value << '\n';
return 0;
}
The documentation for std::condition_variable::wait_for says:
A steady clock is used to measure the duration.
std::chrono::steady_clock:
Class std::chrono::steady_clock represents a monotonic clock. The time points of this clock cannot decrease as physical time moves forward.
Unfortunately, this is gcc Bug 41861 (DR887) - (DR 887)(C++0x) does not use monotonic_clock that it uses system_clock instead of steady_clock for condition variables.
One solution is to use wait_until (be sure to read Notes section) function that allows to specify durations relative to a specific clock. E.g.:
cv.wait_until(lck, std::chrono::steady_clock::now() + std::chrono::seconds(1))
Well, I have created a program which picks up the input signal from serial input. I can successfully receive the data transmitted from the device through UART. I want to terminate the thread after achieving certain conditions( such as receiving more than 5 bytes, etc.) I think the problem is how to terminate the thread in Qt correctly, but I couldn't find the way. The program seems falls into deadlock after calling the exec() in the sub function. Can anyone help with that problem? Thank you very much!
Here's my header file:
#ifndef SERIALTHREAD
#define SERIALTHREAD
#include <QtSerialPort/QSerialPort>
#include <QDebug>
#include <QString>
#include <QThread>
#include <QtCore>
#include <iostream>
#include <fstream>
class SerialControlThread : public QThread
{
Q_OBJECT
public:
explicit SerialControlThread(QString ComPort,QObject *parent = 0);
~SerialControlThread(); // Destructor
bool openSerialPort();
void closeSerialPort();
void run();
bool TelltoExit();
void StarttoRun();
private:
int DataCount;
QString ComPortNumber;
QSerialPort *serial;
int* VoltageStorage; // Total 3 channels, each channel takes 10 data
unsigned int Channel_A[10]; // Channel_A is for Phase Tx s
int DataCountIndexA; // This is how many data has been sent to the buffer;
int SentDataCount;
unsigned char StoreDataBuffer[2];
unsigned char TotalDataCounter;
std::ofstream write;
signals:
void BufferisFull(int*);
void TimeToQuit();
public slots:
private slots:
void readData();
void handleError(QSerialPort::SerialPortError error);
};
#endif // SERIALTHREAD
This is the.cpp
#include "serialcontrol.h"
#include <iostream>
SerialControlThread::SerialControlThread(QString ComPort,QObject *parent) :
QThread(parent),ComPortNumber(ComPort)
{
DataCountIndexA=0;
DataCount=0;
serial = new QSerialPort(this);
connect(this,SIGNAL(TimeToQuit()),this,SLOT(quit()));\
connect(serial, SIGNAL(readyRead()), this, SLOT(readData()));
connect(serial, SIGNAL(error(QSerialPort::SerialPortError)), this,
SLOT(handleError(QSerialPort::SerialPortError)));
for (int i=0;i<10;i++)
Channel_A[i]=0;
}
SerialControlThread::~SerialControlThread()
{
this->closeSerialPort();
delete serial;
}
bool SerialControlThread::openSerialPort()
{
// std::cout << "Hey I am in serial function" << std::endl;
serial->setPortName(ComPortNumber) ;
serial->setBaudRate(QSerialPort::Baud9600); //This can be set through menu in the future
serial->setDataBits(QSerialPort::Data8); // A packets contains 8 bits ( 3 for signature bits)
serial->setParity(QSerialPort::NoParity);
serial->setStopBits(QSerialPort::OneStop);
serial->setFlowControl(QSerialPort::NoFlowControl);
if (!(serial->open(QIODevice::ReadWrite))) {
return false; // return false when the device can't be opened
}else
{
return true;} // return true when the device is avalaible
}
void SerialControlThread::closeSerialPort()
{
if (serial->isOpen())
serial->close();
}
void SerialControlThread::handleError(QSerialPort::SerialPortError error)
{
}
void SerialControlThread::readData()
{
QByteArray data=serial->read(100);
const char *TempChar=data.data();
std::cout << TempChar << std::endl;
DataCount++;
if(DataCount>=4)
{
std::cout << "I am bigger than 4" << std::endl;
this->quit();
}
}
}
void SerialControlThread::run()
{
}
bool SerialControlThread::TelltoExit()
{
}
void SerialControlThread::StarttoRun()
{
// Sending the msp430 S to activate the following sequence
const char *temp="S";
serial->write(temp);
serial->waitForBytesWritten(30000);
this->exec();
}
This is the main.cpp
#include <QCoreApplication>
#include <QtSerialPort/QSerialPortInfo>
#include <QList>
#include <iostream>
#include <QString>
#include <QDebug>
#include <QSerialPort>
#include "serialcontrol.h"
using namespace std;
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
int AvailablePorts=QSerialPortInfo::availablePorts().count();
QList<QSerialPortInfo> SerialObject=QSerialPortInfo::availablePorts();
cout << "There are total: " << SerialObject.count() << " available ports " << endl << endl;
QString description;
for (int i=0;i<AvailablePorts;i++)
{
cout << "The " << i+1 << " com port is :";
qDebug() << SerialObject[i].portName();
qDebug() << "Description : " << SerialObject[i].description();
qDebug() << "Manufacturer: " << SerialObject[i].manufacturer();
cout << endl;
}
SerialControlThread *RunThread=new SerialControlThread(SerialObject[0].portName(),&a);
cout << RunThread->openSerialPort() << endl;
RunThread->StarttoRun();
cout << "I am out of here" << endl;
delete RunThread;
return a.exec();
}
I wish to close the thread( back to the main function) when the buffer has received more than 4 data, but it doesn't.
It is my output
There are total: 1 available ports
The 1 com port is :"COM8"
Description : "MSP430 Application UART"
Manufacturer: "Texas Instruments"
1
0
1
2
3
I am bigger than 4
4
I am bigger than 4
5
I am bigger than 4
6
I am bigger than 4
7
I am bigger than 4
8
I am bigger than 4
9
I am bigger than 4
Apparently, the program gets stuck in a loop. I have tried some solutions, but none of these worked.
StartToRun calls QThread::exec in the wrong thread: you call it in the main thread, but it's supposed to be called in the thread itself - from within run().
Alas, SerialControlThread doesn't have to be a thread. Making it a thread forces it to be used in a dedicated thread - that should be a choice left to its user. Perhaps the thread would be shared among other serial controllers, or perhaps it'll do just fine in the main thread. Thus, it should be an object that handles serial data, that has a thread-safe interface so that you can move it to another thread if you wish - but would still work fine in the main thread, and thus has to handle data asynchronously without blocking.
Considering whether one needs to control the worker thread's run status so tightly: an idle thread consumes no resources - its event loop is blocked waiting on new events, its stack eventually gets paged out if there's memory pressure. If one intends to "wake" the thread for each operation, there's no need to be explicit about it: the event loop in the thread behaves that way be default and by design: it wakes when there are new events, such as incoming data, otherwise it sleeps. One shouldn't be stopping the thread then.
The example below shows a very minimal implementation. On the whole it's not very useful other than to demonstrate brevity as a contrast to the length of code in the question - in spite of identical limited functionality. Presumably you have a more complex communications protocol that you wish to handle. You may wish to consider the use of QDataStream read transactions to make the reader code more expressive, and using a state machine to represent the protocol.
// https://github.com/KubaO/stackoverflown/tree/master/questions/serial-galore-42241570
#include <QtWidgets>
#include <QtSerialPort>
// See https://stackoverflow.com/q/40382820/1329652
template <typename Fun> void safe(QObject * obj, Fun && fun) {
Q_ASSERT(obj->thread() || qApp && qApp->thread() == QThread::currentThread());
if (Q_LIKELY(obj->thread() == QThread::currentThread() || !obj->thread()))
return fun();
struct Event : public QEvent {
using F = typename std::decay<Fun>::type;
F fun;
Event(F && fun) : QEvent(QEvent::None), fun(std::move(fun)) {}
Event(const F & fun) : QEvent(QEvent::None), fun(fun) {}
~Event() { fun(); }
};
QCoreApplication::postEvent(
obj->thread() ? obj : qApp, new Event(std::forward<Fun>(fun)));
}
class SerialController : public QObject {
Q_OBJECT
QSerialPort m_port{this};
QByteArray m_rxData;
void onError(QSerialPort::SerialPortError error) {
Q_UNUSED(error);
}
void onData(const QByteArray & data) {
m_rxData.append(data);
qDebug() << "Got" << m_rxData.toHex() << "(" << m_rxData.size() << ") - done.";
emit hasReply(m_rxData);
}
void onData() {
if (m_port.bytesAvailable() >= 4)
onData(m_port.readAll());
}
public:
explicit SerialController(const QString & port, QObject * parent = nullptr) :
QObject{parent}
{
m_port.setPortName(port);
connect(&m_port, static_cast<void(QSerialPort::*)(QSerialPort::SerialPortError)>(&QSerialPort::error),
this, &SerialController::onError);
}
~SerialController() { qDebug() << __FUNCTION__; }
bool open() {
m_port.setBaudRate(QSerialPort::Baud9600);
m_port.setDataBits(QSerialPort::Data8);
m_port.setParity(QSerialPort::NoParity);
m_port.setStopBits(QSerialPort::OneStop);
m_port.setFlowControl(QSerialPort::NoFlowControl);
return m_port.open(QIODevice::ReadWrite);
}
/// This method is thread-safe.
void start() {
safe(this, [=]{
m_port.write("S");
qDebug() << "Sent data";
});
}
Q_SIGNAL void hasReply(const QByteArray &);
void injectData(const QByteArray & data) {
onData(data);
}
};
QDebug operator<<(QDebug dbg, const QSerialPortInfo & info) {
dbg << info.portName();
if (!info.description().isEmpty())
dbg << " Description: " << info.description();
if (!info.manufacturer().isEmpty())
dbg << " Manufacturer: " << info.manufacturer();
return dbg;
}
// A thread that starts on construction, and is always safe to destruct.
class RunningThread : public QThread {
Q_OBJECT
using QThread::run; // final
public:
RunningThread(QObject * parent = nullptr) : QThread(parent) { start(); }
~RunningThread() { qDebug() << __FUNCTION__; quit(); wait(); }
};
int main(int argc, char *argv[])
{
QCoreApplication app(argc, argv);
auto const ports = QSerialPortInfo::availablePorts();
if (ports.isEmpty())
qFatal("No serial ports");
int n{};
qDebug() << "Available ports:";
for (auto & port : ports)
qDebug() << "port[" << n++ << "]: " << port;
SerialController ctl{ports.at(5).portName()};
if (!ctl.open())
qFatal("Open Failed");
// Optional: the controller will work fine in the main thread.
if (true) ctl.moveToThread(new RunningThread{&ctl}); // Owns its thread
// Let's pretend we got a reply;
QTimer::singleShot(1000, &ctl, [&ctl]{
ctl.injectData("ABCD");
});
QObject::connect(&ctl, &SerialController::hasReply, ctl.thread(), &QThread::quit);
QObject::connect(&ctl, &SerialController::hasReply, [&]{
qDebug() << "The controller is done, quitting.";
app.quit();
});
ctl.start();
return app.exec();
}
#include "main.moc"
I am trying to teach myself C++11 threading, and I would like to start a background producer thread at the beginning of the application, and have it run until application exit. I would also like to have consumer thread (which also runs for the life of the application).
A real-world example would be a producer thread listening on a Com port for incoming GPS data. Once a full message had been accumulated, it could be parsed to see if it was a message of interest, then converted into a string (say), and 'delivered back' to be consumed (update current location, for example).
My issue is I haven't been able to figure out how to do this without blocking the rest of the application when I 'join()' on the consumer thread.
Here is my very simplified example that hopefully shows my issues:
#include <QCoreApplication>
#include <QDebug>
#include <thread>
#include <atomic>
#include <iostream>
#include <queue>
#include <mutex>
#include <chrono>
#include "threadsafequeuetwo.h"
ThreadSafeQueueTwo<int> goods;
std::mutex mainMutex;
std::atomic<bool> isApplicationRunning = false;
void theProducer ()
{
std::atomic<int> itr = 0;
while(isApplicationRunning)
{
// Simulate this taking some time...
std::this_thread::sleep_for(std::chrono::milliseconds(60));
// Push the "produced" value onto the queue...
goods.push(++itr);
// Diagnostic printout only...
if ((itr % 10) == 0)
{
std::unique_lock<std::mutex> lock(mainMutex);
std::cout << "PUSH " << itr << " on thread ID: "
<< std::this_thread::get_id() << std::endl;
}
// Thread ending logic.
if (itr > 100) isApplicationRunning = false;
}
}
void theConsumer ()
{
while(isApplicationRunning || !goods.empty())
{
int val;
// Wait on new values, and 'pop' when available...
goods.waitAndPop(val);
// Here, we would 'do something' with the new values...
// Simulate this taking some time...
std::this_thread::sleep_for(std::chrono::milliseconds(10));
// Diagnostic printout only...
if ((val % 10) == 0)
{
std::unique_lock<std::mutex> lock(mainMutex);
std::cout << "POP " << val << " on thread ID: "
<< std::this_thread::get_id() << std::endl;
}
}
}
int main(int argc, char *argv[])
{
std::cout << "MAIN running on thread ID: "
<< std::this_thread::get_id() << std::endl;
// This varaiable gets set to true at startup, and,
// would only get set to false when the application
// wants to exit.
isApplicationRunning = true;
std::thread producerThread (theProducer);
std::thread consumerThread (theConsumer);
producerThread.detach();
consumerThread.join(); // BLOCKS!!! - how to get around this???
std::cout << "MAIN ending on thread ID: "
<< std::this_thread::get_id() << std::endl;
}
The ThreadSafeQueueTwo class is the thread safe queue implementation taken almost exactly as is from the "C++ Concurrency In Action" book. This seems to work just fine. Here it is if anybody is interested:
#ifndef THREADSAFEQUEUETWO_H
#define THREADSAFEQUEUETWO_H
#include <queue>
#include <memory>
#include <mutex>
#include <condition_variable>
template<typename T>
class ThreadSafeQueueTwo
{
public:
ThreadSafeQueueTwo()
{}
ThreadSafeQueueTwo(ThreadSafeQueueTwo const& rhs)
{
std::lock_guard<std::mutex> lock(myMutex);
myQueue = rhs.myQueue;
}
void push(T newValue)
{
std::lock_guard<std::mutex> lock(myMutex);
myQueue.push(newValue);
myCondVar.notify_one();
}
void waitAndPop(T& value)
{
std::unique_lock<std::mutex> lock(myMutex);
myCondVar.wait(lock, [this]{return !myQueue.empty(); });
value = myQueue.front();
myQueue.pop();
}
std::shared_ptr<T> waitAndPop()
{
std::unique_lock<std::mutex> lock(myMutex);
myCondVar.wait(lock, [this]{return !myQueue.empty(); });
std::shared_ptr<T> sharedPtrToT (std::make_shared<T>(myQueue.front()));
myQueue.pop();
return sharedPtrToT;
}
bool tryPop(T& value)
{
std::lock_guard<std::mutex> lock(myMutex);
if (myQueue.empty())
return false;
value = myQueue.front();
myQueue.pop();
return true;
}
std::shared_ptr<T> tryPop()
{
std::lock_guard<std::mutex> lock(myMutex);
if (myQueue.empty())
return std::shared_ptr<T>();
std::shared_ptr<T> sharedPtrToT (std::make_shared<T>(myQueue.front()));
myQueue.pop();
return sharedPtrToT;
}
bool empty()
{
std::lock_guard<std::mutex> lock(myMutex);
return myQueue.empty();
}
private:
mutable std::mutex myMutex;
std::queue<T> myQueue;
std::condition_variable myCondVar;
};
#endif // THREADSAFEQUEUETWO_H
Here's the output:
I know there are obvious issues with my example, but my main question is how would I run something like this in the background, without blocking the main thread?
Perhaps an even better way of trying to solve this is, is there a way that every time the producer has 'produced' some new data, could I simply call a method in the main thread, passing in the new data? This would be similar to queued signal/slots it Qt, which I am big fan of.
I have a really simple program that works with clang33 under OSX. However if I try to run the same program under Linux it fails. Has anyone got std::asynch to work with clang33 under Linux (CentoOS)?
#include <iostream>
#include <future>
#include <thread>
int main() {
// future from a packaged_task
std::packaged_task<int()> task([]() {
return 7;
}); // wrap the function
std::future<int> f1 = task.get_future(); // get a future
std::thread(std::move(task)).detach(); // launch on a thread
// future from an async()
std::future<int> f2 = std::async(std::launch::async, []() {
return 8;
});
// future from a promise
std::promise<int> p;
std::future<int> f3 = p.get_future();
std::thread([](std::promise<int> & p) {
p.set_value(9);
},
std::ref(p)).detach();
std::cout << "Waiting..." << std::flush;
f1.wait();
f2.wait();
f3.wait();
std::cout << "Done!\nResults are: " << f1.get() << ' ' << f2.get() << ' '
<< f3.get() << '\n';
}
The above example works with trunk/198686 when I compile libc++ with cxxabi. However now I have encountered another problem:
#include <iostream>
#include <vector>
#include <exception>
int main () {
std::vector<int> foo;
try {
foo.at(1);
}
catch (std::exception& e) {
std::cerr << "exception caught: " << e.what() << '\n';
}
std::cout << "Works" << '\n';
return 0;
}
The example code above generates the following expected output under OS X:
exception caught: vector
Works
Under Linux I get the following output:
exception caught: Segmentation fault
I have debugged the code and segmentation fault occurs inside the destructor of logic_error (stdexcept.cpp, line 137). Does anyone have any suggestions?
BTW: Its no longer possible to compile libc++ using the libsupc++ method.
I have actually got everything to work. The above problems occurs with r198686. I checked out the same revision as #BenPope and then everything works as expected.
Thanks,
Patrik
I am trying to read a text file using the following code:
void function readfile(char *inputfile) {
istream is;
int filesize = 0;
is.open(inputfile);
if (!is.is_open()) {
return;
}
is.seekg(0, ios::end);
filesize = (int)is.tellg();
is.seekg(0, ios::beg);
char *buf = new char[filesize];
is.read(buf, filesize);
is.close();
cout << buf << endl;
delete[] buf;
return;
}
While in g++ (mac / macports) it works correctly (getting all contents into a dynamic allocated char* array), in Visual Studio C++ 2010, I get constant errors of this type: Debug assertion failed: (unsigned)(c+1) <= 256, file isctype.c.
The problem is that it opens the file but can't find a termination delimeter so when it reaches the eof it starts reading somewhere else (garbage characters). Using the cout << buf; I can see that the file is being read correctly in mac but in visual c++ it types more garbage chars. What is the problem here?
Make your buffer one larger and add the terminating nul yourself.
Let C++ standard library do the work for you:
void readfile(const char *inputfile) {
std::ifstream is(inputfile);
std::string buf(std::istreambuf_iterator<char>(is), {});
std::cout << buf << std::endl;
}
See, it's now also
exception safe
handles embedded NUL characters correctly
Note, of course you can use vector instead of string if you prefer (just change that one word)
Full demo: see it live on Coliru
#include <fstream>
#include <iostream>
#include <iterator>
void readfile(const char *inputfile) {
std::ifstream is(inputfile);
std::string buf(std::istreambuf_iterator<char>(is), {});
std::cout << buf << std::endl;
}
int main()
{
readfile("main.cpp");
}
Update For C++11 challenged compilers (and showing how to use a vector):
Also Live on Coliru
#include <fstream>
#include <iostream>
#include <iterator>
#include <vector>
void readfile(const char *inputfile) {
std::ifstream is(inputfile);
std::istreambuf_iterator<char> f(is), l;
std::vector<char> buf(f, l);
std::cout.write(buf.data(), buf.size());
}
int main()
{
readfile("main.cpp");
}