cscope's bug? cscope can't find the definition of a function with a function pointer argument - cscope

//main.c
#include "stdio.h"
void f(){
printf("Welcome to emacs's world!");
return;
}
void call_f(void (*f)()){
(*f)();
return;
}
void main(){
call_f(f);
return;
}
I use cscope to find the definition of function "call_f", but have no result, the cscope can't find the definition of "call_f".
I change the argument type of function "call_f" to another type except for a function pointer.
#include "stdio.h"
void f(){
printf("Welcome to emacs's world!");
return;
}
void call_f(/* void (*f)() */void){
// (*f)();
f();
return;
}
void main(){
// call_f(f);
call_f(void);
return;
}
Then cscope can find the definition of function "call_f".
Is that a bug?

Yes, this is a bug. Cscope doesn't implement a full C language parser. Instead it just uses a scanner with a lot of quirks.
For example, cscope also isn't able to recognize function calls/declarations if the opening argument bracket is on the next line like this:
fn_foo
(arg1, arg2);
The bug you found is even documented in cscope's man page:
Nor does it recognize function definitions with a function pointer
argument
ParseTable::Recognize(int startState, char *pattern,
int finishState, void (*FinalAction)(char *))
{
...
}

Related

Passing a function as default argument in another function

How to pass a function as default argument to another function..
For example ...
If the question is.:
Write a program in c++ to print any message using display function and use another function namely input as default argument?
Welcome to stackoverflow. You can use std::function and give it a default, as to be seen in the print function.
#include <iostream>
#include <functional>
void foo() {
std::cout << "foo\n";
}
void bar() {
std::cout << "bar\n";
}
void print(std::function<void()> f = bar) {
f();
}
int main () {
print();
print(foo);
}
For the next question, please show what you did so far and ask from that start a concrete question.

Cant initialise thread in Xcode , C++11

I am trying to implement spsc_queue of boost.
But initialising thread throws error. I cant use both std::thread as well as boost thread.
sharedQueue.hpp
`
#include <stdio.h>
#include <iostream>
#include <queue>
#include <thread>
#include <mutex>
#include <boost/thread.hpp>
#include <boost/lockfree/spsc_queue.hpp>
using namespace std;
class sharedQueue
{
boost::lockfree::spsc_queue<int> lockFreeQ{100};
std::queue<int> comQue;
int head =0;;
int tail = 0;
public:
sharedQueue();
std::mutex lockForQueue;
void write(int writeValue);
int read();
void startTesting();
void TestWrite(int MaxElement);
void lockFreeProduce();
void lockFreeConsume();
void TestLockFreeQueue();
};`
Following is the sharedQueue.cpp
#include "sharedQueue.hpp"
int sharedQueue :: read(){
int readValue;
lockForQueue.lock();
if(!(comQue.empty()))
{
readValue = comQue.front();
comQue.pop();
}
lockForQueue.unlock();
return readValue;
}
void sharedQueue :: write(int writeValue){
lockForQueue.lock();
comQue.push(writeValue);
tail++;
lockForQueue.unlock();
}
void sharedQueue:: startTesting(){
std::cout<<"Size of the que --"<<comQue.size()<<std::endl;
}
void sharedQueue:: TestWrite(int maxEle ){
for(int i = 0 ; i < maxEle; i ++){
write(i);
}
}
void sharedQueue::lockFreeProduce(){
for(int i = 0; i < 10; i++){
cout <<“Produced-- "<< i<<endl;
lockFreeQ.push(i);
}
}
void sharedQueue::lockFreeConsume(){
for(int i = 0; i <10; i++){
lockFreeQ.front();
cout << “ Consume-- "<<lockFreeQ.pop();
}
}
void sharedQueue:: TestLockFreeQueue(){
std::thread t1(lockFreeProduce);
std::thread t2(lockFreeConsume);
t1.join();
t2.join();
} `
I am using Xcode. I have tried changing
C++ Language dialect to c++11 from GNU++11
Standard Library to libc++11 from libstdC++
Please help.
Where am I doing wrong?
You are trying to run a member function as a new thread, not a plain old function. The syntax for member function is different.
void sharedQueue:: TestLockFreeQueue(){
std::thread t1(std::bind(&sharedQueue::lockFreeProduce, this));
std::thread t2(std::bind(&sharedQueue::lockFreeConsume, this));
t1.join();
t2.join();
}
Below answer assumes that we are talking about non-static member function. static member function behaves kind of same way as that of a normal function pointer.
A member function pointer is complex than a plain old function pointer and it cannot be invoked in standalone manner i.e it can only be called when there is an object instance of that class.
See this for an example and read this for better understanding of member function pointers.
An easier way to do it i.e instead of using bind to create a callable object is to use a lambda, C++11 onwards and you should prefer lambda over bind whenever and however possible.
Your example using a lambda:
void sharedQueue:: TestLockFreeQueue(){
std::thread t1([this]() { this->lockFreeProduce(); });
std::thread t2([this]() { this->lockFreeConsume(); });
t1.join();
t2.join();
}
Here I am passing a lambda to the constructor of the thread which creates an anonymous functor structure. The square bracket [...] is the capture list which copies this pointer so that it can be used inside a lambda.
More about lambda can be found here and here.

Arduino 1.6.9/1.610 build fails with "'constexprint' does not name a type"

Supposedly Arduino's IDE > 1.6.2 has C++11 support.
I have just freshly downloaded and run version 1.6.9 on OSX (and as others have reported, this repros on Windows as well, with 1.6.9/1.6.10).
I cannot get this simple program to compile:
constexpr int get_five() { return 5; }
void setup() {
Serial.begin(9600);
Serial.println(get_five());
}
void loop() {
}
I receive this error when I try to build or upload:
sketch_jul25a:1: error: 'constexprint' does not name a type
constexpr int get_five() { return 5; }
^
exit status 1
'constexprint' does not name a type
I've looked at this question and answer, but it is supposedly no longer applicable in 1.6.9 version of the IDE that I am using - error: 'constexpr' does not name a type m- arduino ide
I have dug into the temporary files that are output by the IDE when building, and it seems it is trying to automatically generate headers for functions (I assume for multi-file sketch support), and does the wrong thing when it encounters constexpr:
#include <Arduino.h>
#line 1 "/Users/<my_username>/Documents/Arduino/sketch_jul25a/sketch_jul25a.ino"
#line 1 "/Users/<my_username>/Documents/Arduino/sketch_jul25a/sketch_jul25a.ino"
#line 1 "/Users/<my_username>/Documents/Arduino/sketch_jul25a/sketch_jul25a.ino"
constexprint get_five(); // **** <- This looks to be the culprit
#line 3 "/Users/<my_username>/Documents/Arduino/sketch_jul25a/sketch_jul25a.ino"
void setup();
#line 9 "/Users/<my_username>/Documents/Arduino/sketch_jul25a/sketch_jul25a.ino"
void loop();
#line 1 "/Users/<my_username>/Documents/Arduino/sketch_jul25a/sketch_jul25a.ino"
constexpr int get_five() { return 5; }
void setup() {
Serial.begin(9600);
Serial.println(get_five());
}
void loop() {
}
Is this a bug in the Arduino IDE? Is it unique to OSX? Is there a workaround that allows constexpr to work?
In googling I have found that some Arduino libraries are using constexpr, so I am assuming it could be made to work in some cases.
This is a known limitation of the arduino-builder.
Until it is fixed, you can add a prototype yourself above the function. This will prevent the IDE from incorrectly generating its own.
constexpr int get_five();
constexpr int get_five() { return 5; }
void setup() {
Serial.begin(9600);
Serial.println(get_five());
}
void loop() {
}

C++11 Observers Pass parameters on Notify

I'm coming from C# and trying to implement a simple Events/EventHandler pattern in c++11 which i believe the common name is Observers and signals, i know there are boost library and others but i dont want to use any external libs.
While searching online I found a simple implementation for what I need, so I took and modified the code and it works ok.
My problem is that the parameters are passed when registering events/observers, and not when raising/signaling/notifying which I find a bit awkward.
class EventManager
{
private:
static std::map<EventType, std::vector<std::function<void()>>> _eventHandlers;
public:
EventManager() = default;
template <typename EventHandler>
static void RegisterEventHandler(EventType&& eventType, EventHandler&& eventHandler)
{
EventManager::_eventHandlers[std::move(eventType)].push_back(std::forward<EventHandler>(eventHandler));
}
static void Raise(const EventType& event)
{
for (const auto& eventHandler : EventManager::_eventHandlers.at(event))
{
eventHandler();
}
}
// disallow copying and assigning
EventManager(const EventManager&) = delete;
EventManager& operator=(const EventManager&) = delete;
};
Can anyone help me to extend the following code by adding the functionality to accept parameters when raising the event as well ?
I believe this solves your question:
// g++ -std=c++11 -o /tmp/events /tmp/events.cpp && /tmp/events
// handler=1 arg=1
// handler=2 arg=1
// handler=1 arg=2
// handler=2 arg=2
#include <functional>
#include <map>
#include <vector>
template<class EventType, class... HandlerArgs>
class EventManager
{
public:
using EventHandler = std::function< void(HandlerArgs...) >;
void register_event(EventType&& event, EventHandler&& handler)
{
_handlers[std::move(event)].push_back(std::forward<EventHandler>(handler));
}
void raise_event(const EventType& event, HandlerArgs&&... args)
{
for (const auto& handler: EventManager::_handlers.at(event)) {
handler(std::forward<HandlerArgs>(args)...);
}
}
private:
std::map<EventType, std::vector<EventHandler>> _handlers;
};
int main(int argc, char **argv)
{
EventManager<int, int> m;
m.register_event(1, [](int arg) { printf("handler=%d arg=%d\n", 1, arg); });
m.register_event(1, [](int arg) { printf("handler=%d arg=%d\n", 2, arg); });
m.raise_event(1, 1);
m.raise_event(1, 2);
}
PS: I removed all the code regarding non-copiability and such, since it is not relevant to this question.
Since i havent got any answers on this, i figured a way to do so but i dont like it since i wanted a better way but well creating a static class that has static variables for each event, before raising the event , the caller will set those variables and the handler will read then reset them . this is dangerous approach especially with multi-threading since one or more threads might change the values while raising same event by mutli threads, so i had to implement some locking features to ensure thread safety.
Yes i know its not the best approach but as i'm not an expert in C++ and this question didnt get any comments nor answers, so this is the approach im following.

Passing a lambda to a template function on VC10

I wrote the following code on VC10. Calling f1 is okay, but on calling f2 the compiler showed an error. The difference between the two functions is only "template ", but the template type is actually not used. Why does the error occur?
#include <functional>
void f1( std::tr1::function<void()> f)
{
}
template <typename >
void f2( std::tr1::function<void()> f)
{
}
int main()
{
f1( []{} );
f2( []{} ); // Error C2783
}
Now I understand the error on the first code. How about the following code? Is it the error reason that the compiler can't decide the template type because lambda generates an internal anonymous class, but it is different from std::tr1::function?
#include <functional>
class MyClass
{
};
template <typename T>
void f2( std::tr1::function<void(T)> f)
{
}
int main()
{
std::tr1::function<void(MyClass)> f= [](MyClass v){};
f2( f );
f2( [](MyClass v){} ); // C2784
}
This is not specific to lambdas at all. You need to tell the compiler what version of the template you want to call:
f2<int>([]{});
f2<float>([]{});
It doesn't matter whether you use them or not. It's like unused function parameters:
void f(int) { }
int main() { f(); /* error! */ }

Resources