mardi 30 novembre 2021

Any C++ macro that can export all member variables of a struct for pybind11 [duplicate]

I have some simple structure like:

struct Config {
  bool option1;
  bool option2;
  int arg1;
};

Using pybind11, I have to export the member variables like:

py::class_<Config>(m, "Config")
    .def_readwrite("option1", &Config::option1)
    .def_readwrite("option2", &Config::option2)
    .def_readwrite("arg1", &Config::arg1);

It is ok to write the above for some of these configs. But it becomes tedious when I have lots of this kind of simple structures to config many different targets.

Is there a convenience macro that I can write like:

PYBIND_EXPORT_STRUCT(Config1);
PYBIND_EXPORT_STRUCT(Config2);
...

and each scans and exports all the given struct's member variables?

Will it be helpful if I already write the structs in this form:

struct Config {
    ADD_PROPERTY(bool, option1);
    ADD_PROPERTY(bool, option2);
    ADD_PROPERTY(int, arg1);
}

ADD_PROPERTY() macro was originally used to generate property-like functions: get_var1(), set_var1().

Update

This question involves two parts:

  1. To reflect a variable back to its name string.
  2. To iterate through struct members.

I am aware of introspection to solve the first part, using typeid(arg1).name() to retrieve the name string.

For the second part, C++ does not directly support. However, I am trying to figure it out through some answers here.

The rest of the question is how to fuse the above two parts to get a working implementation for my imagined PYBIND_EXPORT_STRUCT() function.

Edit: that said, I don't mind reformimg my structs into totally different representations (like using some macro, or in tuples). Any will do as long as I don't have to enumerate my struct members again when exporting them with pybind11, and I can still use the variables like 'config1.option1=true' in C code.

enum class with scoping but without having to cast to underlying type

I have this:

enum class Categories : uint32_t {
    C6 = 0x00000020,
    C7 = 0x00000040,
    C8 = 0x00000080,
    ...
};

I chose an enum class because it is great for scoping. But the downside is that when I need to use the categories as mask bits for bitwise operations I need to cast them to uint32_t first.

Example:

uint32_t masterCat = ((uint32_t)MyClass::Categories::C6) | ((uint32_t)MyClass::Categories::C7);

Is there a way I can get the same scoping benefit, without having to cast before using each time ? If I use a regular enum, then I lose the scoping benefit :(

Example:

uint32_t masterCat = (MyClass::Categories::C6) | (MyClass::Categories::C7);

Segmentation Fault while getting input from 2D vector

I get a segmentation fault when I run the code below.

int main()
{

    int R, C, val;
    cin>>R>>C;
    vector<vector<int>> a;
    for(int i = 0; i < R; i++)
    {
        for(int j = 0; j < C; j++)
        {
             cin>>val;
             a[i].push_back(val);
        }
    }

But when I change it to this, it seems to work. What is the reason?

int main()
{

    int R, C, val;
    cin>>R>>C;
    vector<vector<int>> a;
    for(int i = 0; i < R; i++)
    {
        vector<int>temp;
        for(int j = 0; j < C; j++)
        {
             cin>>val;
             temp.push_back(val);
        }
        a.push_back(temp);
    }

I get the same fault no matter what the value of R and C is kept.

C++: Member function call forwarding using variadic data structure

I am trying to create a class (similar to std::tuple) which can hold a variable number of references to objects of different type and which can forward a call to a specific member function to all of its constituents. Here is an example:

// g++ Test7.C -std=c++17 -o Test7

#include <iostream>

struct P1 { void operator()(void) const { std::cout<<"P1 "; } };
struct P2 { void operator()(void) const { std::cout<<"P2 "; } };
struct P3 { void operator()(void) const { std::cout<<"P3 "; } };

template <class... EmitterList> struct Emitters 
{
 inline void operator()(void) const { std::cout<<std::endl; }
};

template <class Emitter, class... EmitterList>
class Emitters<Emitter,  EmitterList...> : public Emitters<EmitterList...>
{
public:
 using Base = Emitters<EmitterList...>;

 Emitters(const Emitter & e, const EmitterList & ... eList)
  : emitter(e), Base(eList...) {}

 inline void operator()(void) const { emitter(); this->Base::operator()(); }
private:
 const Emitter & emitter;
};

int main(void)
{
 P1 p1;
 P2 p2;
 P3 p3;
 Emitters e0;           e0(); // works
 //Emitters e1{p1};       e1(); // does not work
 //Emitters e2{p1,p2};    e2(); // does not work
 //Emitters e3{p1,p2,p3}; e3(); // does not work
 return 0;
}

The expectation is that e1() would output "P1 \n" (calls p1()), e2() would output "P1 P2 \n" (calls p1(); p2()), and e3() would output "P1 P2 P3 \n" (calls p1(); p2(); p3();). But something is not right in the code: it compiles for e0 but not for the other cases. Could you please help me to understand what I am doing not right here and how to fix it?

Thank you very much for your help!

Does always int i{0} be faster then int i = 0?

int i{0}; //(1)
int i = 0; //(2)

Do I have correct understanding that in first case (1) the variable i will be created already with 1 as it's value, and in (2) it will be created without a value and then assigned a value 1, so (1) will always faster then (2)?

But seems like most(all?) modern compilers will still optimize (2) to be same as (1) under the hood?

Can you add null terminators to a C++11 string and iterate over them?

In C++11, is it legal to put null terminators in a C++11 string and then iterate over the entire length of the string?

#include <string>
#include <iostream>

int main(int argc, char** argv) {
   std::string s("\0\0hello\0world\n");

   for (char c : s) {
       std::cout << " " << (unsigned int)c;
   }
   std::cout << std::endl;
   return 0;
}

Compilation Error - Binding reference discards qualifiers

I am getting this compilation error when trying to compile inher2.cpp How do I correctly assign eventQueue to m_eventQueue ? I made this MSVP to see if I could proceed further but haven't been successful.

inher2.cpp:7:26: error: binding reference of type ‘std::shared_ptr<EventQueue>&&’ to ‘std::remove_reference<const std::shared_ptr<EventQueue>&>::type {aka const std::shared_ptr<EventQueue>}’ discards qualifiers
  m_eventQueue = std::move(eventQueue);
                 ~~~~~~~~~^~~~~~~~~~~~

inher2.cpp

#include<iostream>
#include"inher2.hpp"

RecordingConfigJobStateSignal::RecordingConfigJobStateSignal( const EventQueuePtr& eventQueue )
{
        /* m_eventQueue is actually from class commonQueue */
        m_eventQueue = std::move(eventQueue);
}

int main()
{
        return 0;
}

inher2.hpp

#include<iostream>
#include<memory>
#include<queue>
using namespace std;
class EventBase
{
public:

private:
        int a;
};
using EventBasePtr = std::shared_ptr<EventBase>;

class SubscriptionManager
{

        public:
                int x;
};

class EventQueue
{
public:
    explicit EventQueue( SubscriptionManager& );
    ~EventQueue();
    EventQueue& operator = (const EventQueue &)
    {
        return *this;
    }
private:
    std::queue< EventBasePtr >          m_queue;
};
using EventQueuePtr = std::shared_ptr<EventQueue>;


class commonQueue
{
        public:
                int *a;
                static std::queue< EventBasePtr >       m_queue;
                const EventQueuePtr m_eventQueue;
};

class RecordingConfigJobStateSignal: public commonQueue
{
        public:
                int c;
                RecordingConfigJobStateSignal( const EventQueuePtr &);
        private:
                int b;

};

I fixed one error prior to this by using std::move but stuck at the error discussed above.

inher2.cpp:7:17: error: cannot bind rvalue reference of type ‘std::shared_ptr<EventQueue>&&’ to lvalue of type ‘const EventQueuePtr {aka const std::shared_ptr<EventQueue>}’
  m_eventQueue = eventQueue;
                 ^~~~~~~~~~

Writing to existing Sales_data object in std::vector causes program to crash (C++)

Hope you're all doing well!

I'm reading and doing the exercises in Stanley Lippman's C++ Primer Ed.5.

I'm having the following issue with my code, when I update an existing Sales_data object in the std::vector<Sales_data> vec; the program crashes.

In order to over come this I erase the existing Sales_data object and replace it with a new updated object.

Is there a more efficient way of doing this without erasing the Sales_data object and then replacing it?

My CODE:

#include <iostream>
#include <vector>

/*
struct: Sales_data
attributes: total revenue, number of copies sold, average sales price for a book

*/

struct Sales_data
{
    //Exercise 7.2
    std::string isbn() const{return this->bookNo;}
    Sales_data& combine(const Sales_data &rhs)
    {
        this->units_sold += rhs.units_sold;
        this->revenue += rhs.revenue*rhs.units_sold;
        return *this;
    }

    Sales_data add(const Sales_data &lhs, const Sales_data &rhs)
    {
        Sales_data sum =lhs;
        sum.combine(rhs);
        return sum;
    }

    std::string bookNo;
    unsigned units_sold =0;
    double revenue =0.0;
};

int main()
{
    Sales_data book;
    std::vector<Sales_data> vec;
    bool isDuplicate = false;

        while(std::cin>>book.bookNo>>book.units_sold>>book.revenue)
        {
            for(auto it =vec.begin(); !vec.empty()&&it!=vec.end(); ++it)
            {
                if(book.bookNo == it->isbn()) //can also be written to dereference the it pointer (*it).bookNo
                {
                    Sales_data add_book =it->add(*it, book);

                    vec.erase(it); //must erase to prevent a crash
                    vec.push_back(add_book);//push add_book obj in vec position
                    isDuplicate = true;
                }
            }

          if(!isDuplicate)
            {
                vec.push_back(book);
            }

            for(size_t i=0; i!=vec.size(); ++i)
            {
                std::cout<<vec[i].isbn()<<"  "<<vec[i].units_sold<<"  "<<vec[i].revenue<<std::endl;
            }

          isDuplicate = false;
        }

    return 0;
}

//Thank you.

Arduino IR code not working (USING TINKERCAD)

ARDUINO PROBLEM

enter image description here

**So this is the circuit bord **

THE PROBLEM: when I try to run the code and try to press any button on the IR remote it does nothing ( it doesn't print the hexacode ! )

  • I have tried to change the circuit and tried to change the code. I was looking fro the arduino forums and tried every one, but still it doesn't work .
  • Is there a problem with tinkercad. simulation or is it with the code ?

CODE: https://pastebin.com/1Uhn1j3a

CODE:


#include <IRremote.h>

const int RECV_PIN = A5;
IRrecv irrecv(RECV_PIN);
decode_results results;

void setup(){
  Serial.begin(9600);
  irrecv.enableIRIn();
  irrecv.blink13(true);
}

void loop(){
  if (irrecv.decode(&results)){
        Serial.println(results.value, HEX);
        irrecv.resume();
  }
}

Enumerator value evaluates to 2147483648, which cannot be narrowed to type 'int'

I created an enum like this:

enum class CATEGORIES{
       C01 = 0x00000001,
       C02 = 0x00000002,
       C03  = 0x00000004,
       ...
       C26 = 0x02000000,
       C27 = 0x04000000,
       C28 = 0x08000000,
       C29 = 0x10000000,
       C30 = 0x20000000,
       C31 = 0x40000000,
       C32 = 0x80000000, //Error at this line
    }

Enumerator value evaluates to 2147483648, which cannot be narrowed to type 'int'

How should I resolve it? I just wanted a convenient way of representing the categories, and enum class seemed to make sense for namespacing..

lundi 29 novembre 2021

Initializer list C++ in class diagram

I just study class diagram for a few days ago and now I meet a problem where the constructor has its initializer list, is there any way to show the initializer list in class diagram, with example would be good, thank you in advance.

Retrieve block data from file in C++ [closed]

I have a file with the following structure:

File

title1
(
    data1
    ( 
        variableName   1   
    )


   data2
   (
       variableName2 someString someOtherVariable
   )

)

I would like to create a class that would retrieve the information between parenthesis.

What C++ data type is more suitable to collect this information?

Would it be efficient to go into the file, find a keyWord and the opening and closing parenthesis and return a structure with file path, starting and end line. And implement functions to look into the file? Is there something of kind already built into C++?

I would appreciate suggestions on the strategy.

Bubble sort in double linked list

void sortTrain(TrainCar* head, bool ascending)
{
    TrainCar* current = head;
    int count = 1;
    int size = (getlength(head));
    if (ascending == 1)
    {
        for(int i = 0; i < size-1; i++)
        {
            while(current->next)
            {
                if((current->load) > ((current->next)->load))
                {
                    swapCar(head,count,count+1);
                }
                count++;
                current = current->next;
            }
        }
    }

    if (ascending == 0)
    {
        for(int i = 0; i < size-1; i++)
        {
            while(current->next)
            {
                if((current->load) < ((current->next)->load))
                {
                    swapCar(head,count,count+1);
                }
                count++;
                current = current->next;
            }
        }
    }
}

Anyone helps me to fix the problem? I don't know how to improve it. Or any other code can do the same result? Ascending when bool ascending is true, otherwise, do descending.

How to pass a C++ Template instance to a function?

How can I pass any object of an templated class to another function in C++11?

In the snippet below passInObj does not compile because it complains about Printer&. I want to pass in any Printer it does not matter which template T I have used.

How can I do this and why does the solution below not work?

#include <iostream>
#include <vector>
template <typename T>
class Printer {
  public:
   Printer(const T& tl) : t(tl) {}
   void print() const {
     for (auto x : t) {
        std::cout << x << std::endl;
      }
   }
   const T &t;
};

// THIS LINE DOES NOT COMPILE
void passInObj(const Printer& p) {
   p.print();
}

int main() {
  std::vector<std::string> vec;
  vec.push_back("ABC");
  Printer<std::vector<std::string>> printer(vec);
  printer.print();
  passInObj(p);
  return 0;
}

counting number of elements less than X in a BST

I had implemented a BST for a multiset using the C++ code below, whereas each node contains the number of occurrence num of each distinct number data, and I try to find the number of elements less than certain value x, using the order function below.

It works, however, inefficient in terms of execution time. Is there any method with better time complexity?

struct Node {
    int data;
    int height;
    int num;

    Node *left;
    Node *right;
};
int order(Node *n, int x) {
    int sum = 0;
    if (n != NULL) {
        if (n->data < x) {
            sum += n->num;
            sum += order(n->right, x);
        }
        sum += order(n->left, x);
    }
    return sum;
}

Class not recognised when included in header file in C++ [closed]

I'm trying to create a basic text adventure game using C++. I'm declaring the classes I use in header files, then including them where needed. For some reason, one header file does not recognise one header file included in it, and is not recognised by my main program.

The header file that seems to be causing the problem is State.h (this represents the game state and related functions):

#ifndef TEXTADV_STATE_H
#define TEXTADV_STATE_H

#include "Room.h"
#include "GameObject.h"

class State {
    Room *currentRoom;
    Room *previousRoom;
public:
    explicit State(Room *startRoom);
    static std::list<GameObject> inventory;
    void goTo(Room *target);
    void goBack();
    void announceLoc() const;
    Room* getCurrentRoom() const;
    Room* getPrevRoom() const;
};


#endif //TEXTADV_STATE_H

State.h does not recognise the GameObject class, despite the header file being included. The same class is recognised without issue in another header file: Room.h.

GameObject.h:

#ifndef TEXTADV_STATE_H
#define TEXTADV_STATE_H

#include <iostream>

using std::string;

class GameObject{
    string s_name;
    string desc;
    string keyword;
public:
    /** constructor */
    GameObject(const string *_s_name, const string *_desc, const string *_keyword);

    string getName();
    string getDesc();
    string getKeyword();
};

#endif //TEXTADV_STATE_H

Room.h:

#ifndef TEXTADV_ROOM_H
#define TEXTADV_ROOM_H

#include <string>
#include <forward_list>
#include <list>
#include "GameObject.h"

using std::string;

/**
 * Represents a room (accessible location in the game).
 */
class Room {
    /**
     * Short name used as a header.
     */
    const string* name;
    /**
     * Full description of the room.
     */
    const string* description;
    /**
     * Pointer to room that is n/s/e/w of this one.
     */
    Room* north;
    Room* south;
    Room* east;
    Room* west;

public:
    /**
     * Constructs a new Room.
     * @param _name Name of the room.
     * @param _desc Description of the room.
     */
    Room(const string *_name, const string *_desc);

    /**
     * Removes a destroyed room from the global list if it's there.
     */
    ~Room();

    /**
     * Outputs the name and description of the room
     * in standard format.
     */
    void describe() const;

    /**
     * List storing all rooms that have been registered via addRoom().
     */
    static std::list<Room*> rooms;

    /**
     * list of game objects in room
     */
    static std::list<GameObject*> room_objs;
    static std::list<GameObject*>::iterator obj_it;

    /**
     * Creates a new Room with the given parameters and register it with the static list.
     * @param _name Name of the room.
     * @param _desc Description of the room.
     */
    static Room* addRoom(const string* _name, const string* _desc);
    static void addRoom(Room* room);

    static void addObj(GameObject* obj) {};


    Room* getNorth() const;
    Room* getSouth() const;
    Room* getEast() const;
    Room* getWest() const;
    void setNorth(Room* _north);
    void setSouth(Room* _north);
    void setEast(Room* _north);
    void setWest(Room* _north);

};

#endif //TEXTADV_ROOM_H

Finally, my main programme main.cpp does not recognise the State.h file either. It previously did and I'm not sure what's changed (to my knowledge I haven't changed anything in either file that would change the relation/include) for this to happen.

main.cpp:

#include <iostream>
#include <iomanip>
#include <memory>
#include <iterator>
#include <vector>
#include <forward_list>
#include "Room.h"
#include "wordwrap.h"
#include "State.h"
#include "strings.h"
#include "GameObject.h"


using std::string;
using std::unique_ptr;

string commandBuffer;

State *currentState;

/**
 * Print out the command prompt then read a command into the provided string buffer.
 * @param buffer Pointer to the string buffer to use.
 */
void inputCommand(string *buffer) {
    buffer->clear();
    std::cout << "> ";
    std::getline(std::cin, *buffer);
}

/**
 * Sets up the map.
 */
void initRooms() {
    auto * r2 = new Room(&r2name, &r2desc);
    auto * r1 = new Room(&r1name, &r1desc);
    auto * r3 = new Room(&r3name, &r3desc);
    auto * r4 = new Room(&r4name, &r4desc);
    auto * r5 = new Room(&r5name, &r5desc);
    auto * obj1 = new GameObject(&obj1name, &obj1desc, &obj1keyw);
    Room::addObj(obj1);
    Room::addRoom(r1);
    Room::addRoom(r2);
    Room::addRoom(r3);
    r1->setNorth(r2);
    r1->setSouth(r3);
    r1->setEast(r4);
    r1->setWest(r5);


}

/**
 * Sets up the game state.
 */
void initState() {
    currentState = new State(Room::rooms.front());
}


/**
 * The main game loop.
 */
void gameLoop() {
    bool gameOver=false;
    while (!gameOver) {
        /* Ask for a command. */
        bool commandOk = false;
        inputCommand(&commandBuffer);

        /* The first word of a command would normally be the verb. The first word is the text before the first
         * space, or if there is no space, the whole string. */
        auto endOfVerb = static_cast<uint8_t>(commandBuffer.find(' '));

        /* We could copy the verb to another string but there's no reason to, we'll just compare it in place. */
        /* Command to go north. */
        if ((commandBuffer.compare(0,endOfVerb,"north") == 0) || (commandBuffer.compare(0,endOfVerb,"n") == 0)) {
            commandOk = true; /* Confirm command has been handled */
            /* See if there's a north exit */
            Room *northRoom = currentState->getCurrentRoom()->getNorth();
            if (northRoom == nullptr) { /* there isn't */
                wrapOut(&badExit);      /* Output the "can't go there" message */
                wrapEndPara();
            } else {                    /* There is */
                currentState->goTo(northRoom); /* Update state to that room - this will also describe it */
            }
        }
        if ((commandBuffer.compare(0,endOfVerb,"south") == 0) || (commandBuffer.compare(0,endOfVerb,"s") == 0)) {
            commandOk = true; /* Confirm command has been handled */
            /* See if there's a south exit */
            Room *southRoom = currentState->getCurrentRoom()->getSouth();
            if (southRoom == nullptr) { /* there isn't */
                wrapOut(&badExit);      /* Output the "can't go there" message */
                wrapEndPara();
            } else {                    /* There is */
                currentState->goTo(southRoom); /* Update state to that room - this will also describe it */
            }
        }
        if ((commandBuffer.compare(0,endOfVerb,"east") == 0) || (commandBuffer.compare(0,endOfVerb,"e") == 0)) {
            commandOk = true; /* Confirm command has been handled */
            /* See if there's a east exit */
            Room *eastRoom = currentState->getCurrentRoom()->getEast();
            if (eastRoom == nullptr) { /* there isn't */
                wrapOut(&badExit);      /* Output the "can't go there" message */
                wrapEndPara();
            } else {                    /* There is */
                currentState->goTo(eastRoom); /* Update state to that room - this will also describe it */
            }
        }
        if ((commandBuffer.compare(0,endOfVerb,"west") == 0) || (commandBuffer.compare(0,endOfVerb,"w") == 0)) {
            commandOk = true; /* Confirm command has been handled */
            /* See if there's a west exit */
            Room *westRoom = currentState->getCurrentRoom()->getWest();
            if (westRoom == nullptr) { /* there isn't */
                wrapOut(&badExit);      /* Output the "can't go there" message */
                wrapEndPara();
            } else {                    /* There is */
                currentState->goTo(westRoom); /* Update state to that room - this will also describe it */
            }
        }
        if ((commandBuffer.compare(0,endOfVerb,"back") == 0) || (commandBuffer.compare(0,endOfVerb,"b") == 0)) {
            commandOk = true; /* Confirm command has been handled */
            /* See if there's a previous room */
            Room *prevRoom = currentState->getPrevRoom();
            if (prevRoom == nullptr) { /* there isn't */
                wrapOut(&badExit);      /* Output the "can't go there" message */
                wrapEndPara();
            } else {                    /* There is */
                currentState->goBack(); /* Update state to that room - this will also describe it */
            }
        }

        /* Quit command */
        if ((commandBuffer.compare(0,endOfVerb,"quit") == 0)) {
            commandOk = true;
            gameOver = true;
        }

        /* If commandOk hasn't been set, command wasn't understood, display error message */
        if(!commandOk) {
            wrapOut(&badCommand);
            wrapEndPara();
        }
    }
}


int main() {
    initWordWrap();
    initRooms();
    initState();
    currentState->announceLoc();
    gameLoop();
    return 0;
}

I've tried using #ifndef #define but this does not solve the issue either. I've also tried recompiling and rebuilding but no joy there either. I'm absolutely stuck as to why State.h and GameObject.h are recognised in some files but not others. Any ideas?

Thank you.

Variable not set inside __attribute__((constructor)) or global static variable reset after __attribute__((constructor)) invoked

I have a std::vector which need to filled with some random values when library is loaded. but I see it is been reset after library is loaded. Is it because of global and static

Library code:

static std::vector<uint8_t> g_randomNr{};


__attribute__((constructor)) void generateRandomNrAtStart(void)
{
    static bool firstLoad = false;
    g_randomNr.clear();
    if (!firstLoad) {
        firstLoad = true;
        std::cout << "Library is loaded and generating first random number ...\n";
    }

    std::cout << "Generating random number ...\n";


    for (int i = 0; i < 20; i++) {
        g_randomNr.push_back(i);
    }

    std::cout << "Random number generated with length of " << g_randomNr.size() << "\n";
}

void getRandomNr(std::vector<uint8_t>& randomNr)
{
    randomNr = g_randomNr;
}

Main code:

int main()
{
    std::vector<uint8_t> randomNr{};
    getRandomNr(randomNr);
    
    std::cout << randomNr.size() << "\n";
    return 0;
}

Output:

Library is loaded and generating first random number ...
Generating random number ...
Random number generated with length of 20
0

In the above output I expect 20 in cout main function but I receive empty vector

Unexpected behavior concatenating string

I am trying to concatenate two strings in C++11 and I am often getting an unexpected behavior.

First, I have a function that converts any type to string :

template <class T>
static inline const char * toStr(T arg) {
    stringstream ss;
    ss << arg;
    return (ss.str()).c_str();
}

Then, I use this function like this :

string measure_name;
for (unsigned long j = 0; j < 1280; j++) {
    measure_name = string("ADC_") + toStr(j);
    cout << measure_name << endl;
}

Everything goes well untill I reach a 4 digit number (> 999) : my variable measure_name often equals to "ADC_ADC_"... and it happens randomly. I did some research and found nothing about this strange behavior.

For your information, this issue is fixed if toStr returns a string and not a const char *.

Also, if I try to print the returned value, I never see it equal to "ADC_ADC_", so I believe the real issue comes from the concatenating instruction :

string measure_name;
for (unsigned long j = 0; j < 1280; j++) {
    const char* tmp = toStr(j);
    if (!strcmp(toStr(j), "ADC_ADC_"))
        cout << "bug" << endl; //never happens
    measure_name = string("ADC_") + tmp; //problem comes from here
    cout << measure_name << endl;
}

I just wanted to understand what I am doing wrong there... I know I am using very old C++ but it should work anyway.

Thank's for your help.

dimanche 28 novembre 2021

Why my cpp-netlib server stuck at std::condition_variable::wait when process POST request?

I'm writing an async HTTP server and client using cpp-netlib based on the given "Hello World" example. The server can process GET request, but can't get the request body of POST request. Then I saw the Issue-823 of the cpp-netlib and add an async connection handler. The struct as follows(Changed from the "file upload" example):

///
/// Custom exception type
///
struct file_uploader_exception : public std::runtime_error {
    file_uploader_exception(const std::string err) :
        std::runtime_error(err) {
    }
};

///
/// Encapsulates request & connection
///
struct file_uploader : std::enable_shared_from_this<file_uploader> {
    const server::request& req;
    server::connection_ptr  conn;

    std::mutex              mtx;
    std::condition_variable condvar;

    //FILE* fp = NULL;
    std::string body;

public:
    file_uploader(const server::request& req, const server::connection_ptr& conn)
        : req(req)
        , conn(conn) {
        /*const std::string dest = destination(req);

        if (dest.find("/upload") != std::string::npos) {
            auto queries = get_queries(dest);
            auto fname = queries.find("filename");
            if (fname != queries.end()) {
                fp = ::fopen(fname->second.c_str(), "wb");
                if (!fp) {
                    throw file_uploader_exception("Failed to open file to write");
                }
            }
            else {
                throw file_uploader_exception("'filename' cannot be empty");
            }
        }*/
    }

    ~file_uploader() {
        /*if (fp) {
            ::fflush(fp);
            ::fclose(fp);
        }*/
    }

    ///
    /// Non blocking call to initiate the data transfer
    ///
    void async_recv() {
        std::cout << "async_recv()" << std::endl;
        std::size_t content_length = 0;
        auto const& headers = req.headers;
        for (auto item : headers) {
            if (boost::to_lower_copy(item.name) == "content-length") {
                content_length = std::stoll(item.value);
                break;
            }
        }

        read_chunk(conn, content_length);
    }

    ///
    /// The client shall wait by calling this until the transfer is done by
    /// the IO threadpool
    ///
    void wait_for_completion() {
        std::cout << "wait_for_completion()" << std::endl;
        std::unique_lock<std::mutex> _(mtx);
        condvar.wait(_);
    }

private:
    ///
    /// Parses the string and gets the query as a key-value pair
    ///
    /// @param [in] dest String containing the path and the queries, without the fragment,
    ///                  of the form "/path?key1=value1&key2=value2"
    ///
    std::map<std::string, std::string> get_queries(const std::string dest) {
        std::cout << "get_queries()" << std::endl;

        std::size_t pos = dest.find_first_of("?");

        std::map<std::string, std::string> queries;
        if (pos != std::string::npos) {
            std::string query_string = dest.substr(pos + 1);

            // Replace '&' with space
            for (pos = 0; pos < query_string.size(); pos++) {
                if (query_string[pos] == '&') {
                    query_string[pos] = ' ';
                }
            }

            std::istringstream sin(query_string);
            while (sin >> query_string) {

                pos = query_string.find_first_of("=");

                if (pos != std::string::npos) {
                    const std::string key = query_string.substr(0, pos);
                    const std::string value = query_string.substr(pos + 1);
                    queries[key] = value;
                }
            }
        }

        return queries;
    }

    ///
    /// Reads a chunk of data
    ///
    /// @param [in] conn        Connection to read from
    /// @param [in] left2read   Size to read
    ///
    void read_chunk(server::connection_ptr conn, std::size_t left2read) {
        std::cout << "read_chunk()" << std::endl;
        conn->read(boost::bind(&file_uploader::on_data_ready,
            file_uploader::shared_from_this(),
            _1, _2, _3, conn, left2read));
    }

    ///
    /// Callback that gets called when the data is ready to be consumed
    ///
    void on_data_ready(server::connection::input_range range,
        boost::system::error_code error,
        std::size_t size,
        server::connection_ptr conn,
        std::size_t left2read) {
        std::cout << "on_data_ready()" << std::endl;
        if (!error) {
            //::fwrite(boost::begin(range), size, 1, fp);
            body.append(boost::begin(range), boost::begin(range) + size);
            std::size_t left = left2read - size;
            if (left > 0)
                read_chunk(conn, left);
            else
                wakeup();
        }
    }

    ///
    /// Wakesup the waiting thread
    ///
    void wakeup() {
        std::cout << "wakeup()" << std::endl;
        std::unique_lock<std::mutex> _(mtx);
        condvar.notify_one();
    }
};

When I use my client or curl to perform a POST request, the server outputs as follows:

PS F:\CBPLibary\x64\Release> .\ServerTest.exe 0.0.0.0 40000
async_recv()
read_chunk()
wait_for_completion()

Then it stucks.The server does not respose to any other request, and the client stucks too. I want to know why this happened and how to solve it. My server code:

struct hello_world {
    void operator()(server::request const& request, server::connection_ptr connection) {
        std::shared_ptr<file_uploader> uploader(new file_uploader(request, connection));
        uploader->async_recv();
        uploader->wait_for_completion();
        std::cout << uploader->body << std::endl;
        server::string_type ip = source(request);
        server::response_header headers[] = { {"Connection","close"} ,{"Content-Type", "text/plain"} };
        unsigned int port = request.source_port;
        std::ostringstream data;
        data << "Hello, " << ip << '[' << port << "]!";
        connection->set_headers(boost::make_iterator_range(headers, headers + 2));
        connection->set_status(server::connection::ok);
        connection->write(data.str());
    }
};
int main(int argc, char* argv[]) {

    if (argc != 3) {
        std::cerr << "Usage: " << argv[0] << " address port" << std::endl;
        return 1;
    }

    try {
        hello_world handler;
        server::options options(handler);
        options.thread_pool(std::make_shared<boost::network::utils::thread_pool>());
        server server_(options.address(argv[1]).port(argv[2]));
        std::thread t_server([&server_] { server_.run(); });
        //server_.run();
        t_server.detach();
        char ch;
        do
        {
            ch = getchar();
        } while (ch != '0');
        server_.stop();
    }
    catch (std::exception& e) {
        std::cerr << e.what() << std::endl;
        return 1;
    }

    return 0;
}

My client code:

namespace http = boost::network::http;
using header = std::pair<std::string, std::string>;
int main(int argc, char* argv[]) {
    if (argc != 3) {
        std::cerr << "Usage: " << argv[0] << " address port" << std::endl;
        return 1;
    }

    try {
        std::string post_body = "test";
        http::client client;
        std::ostringstream url;
        url << "http://" << argv[1] << ":" << argv[2] << "/command";
        http::client::request request(url.str());
        request.add_header(header("Connection", "keep-alive"));
        request.add_header(header("Content-Type", "text/plain"));
        //http::client::response response = client.get(request);
        http::client::response response = client.post(request, post_body);
        std::cout << body(response) << std::endl;
    }
    catch (std::exception& e) {
        std::cerr << e.what() << std::endl;
        return 1;
    }
    return 0;
}

The curl command I use:

curl.exe -d "test" -X POST http://127.0.0.1:40000/command

My develop environment:

OS: Windows 11 build 22504
boost library version: 1.77.0
cpp-netlib version: 0.13.0
IDE: Visual Studio 2022 (MSVC17,Build tool v143)

Question regarding polymorphiic functions in C++

I am new to C++ and currently I am studying polymorphism.

I have this code:

#include <iostream>
class Base
{
    public:
        void say_hello()
        {
            std::cout << "I am the base object" << std::endl;
        }
};


class Derived: public Base
{
    public:
        void say_hello()
        {
            std::cout << "I am the Derived object" << std::endl;
        }
};

void greetings(Base& obj)
{
    std::cout << "Hi there"<< std::endl;
    obj.say_hello();
}



int main(int argCount, char *args[])
{

    Base b;
    b.say_hello();

    Derived d;
    d.say_hello();

    greetings(b);

    greetings(d);

    return 0;
}

Where the output is:

I am the base object
I am the Derived object
Hi there
I am the base object
Hi there
I am the base object

This is not recognizing the polymorphic nature in the greetings functions.

If I put the virtual keyword in the say_hello() function, this appears to work as expected and outputs:

I am the base object
I am the Derived object
Hi there
I am the base object
Hi there
I am the Derived object

So my question is: The polymorphic effect is retrieved when using a pointer/reference?

When I see tutorials they will present something like:

Base* ptr = new Derived();
greetings(*ptr);

And I was wondering if had to always resort to pointers when using polymorphism.

Sorry if this question is too basic.

C++ istream_iterator doesn't work after initial use

I'm learning about C++ iterators and I'm having trouble with the following piece of code. It simply reads in a text file data.txt that has a series of integers in it, and prints the contents to the console, twice. The initial print loop works fine, but the second one stops after the first entry. Why does this happen?

#include <iterator>  // 
#include <iostream>  // 
#include <fstream>   // 

int main(void)
{
    std::ifstream ifstream_0("data.txt");
    std::istream_iterator<int> istream_iterator_0(ifstream_0), end;
    
    // print out contents
    for (auto it = istream_iterator_0; it != end; it++) 
    {
        std::cout << *it << std::endl;
    } 

    // print out contents again, but this stops after the first entry
    for (auto it = istream_iterator_0; it != end; it++) 
    {
        std::cout << *it << std::endl;
    }
}

data.txt looks like this:

1 2 3 4 5 6

The output of the program is the following:

1
2
3
4
5
6
1

My question is, why does the second print loop stop after the first entry, "1" ?

Can you show me way how to see all functions that be supplied by particular lib?

Ex: all functions in iostream.h

I want to input the names as a string but I'm not able to do it correctly after the first input in C++

I want to input a string from the user and in doing so by the following code, I'm only able to input the first string correctly, other strings are showing some garabage value, please help.

#include<iostream>
#include<string.h>
using namespace std;
//Creating Arrays in OOPS
class Employee
{
    private:
        string name;
        int id;
        float salary;
    public:
        void setName(void)
        {
            cout<<"The name of your employee is "<<endl;
            getline(cin,name);
        }
        void setId(void)
        {
            cout<<"Enter the id of the employee"<<endl;
            cin>>id;
        }
        void getData(void)
        {
            cout<<"The name of your employee is "<<name<<endl;
            cout<<"The id of the employee is "<<id<<endl;
        }
};

int main()
{
    Employee svt[7];
    
        for(int i=0; i<7;i++)
        {
            svt[i].setName();
            svt[i].setId();
            svt[i].getData();
        }
    
    return 0;
}

Function Template Type Deduction Rules

I have:

template<typename ...Ts, typename U, typename=void>
void valid(Ts..., U){}

int main() {
    valid(1.0, 1, 2, 3);
}

clang complains:

note: candidate function [with Ts = <>, U = double, $2 = void] not viable: requires 1 argument, but 4 were provided
void valid(Ts..., U){}
     ^

And gcc complains:

<source>:2:6: note:   template argument deduction/substitution failed:
<source>:5:10: note:   candidate expects 1 argument, 4 provided
    5 |     valid(1.0, 1, 2, 3);
      |     ~~~~~^~~~~~~~~~~~~~

According to cling, it seems like the compiler deduces that Tn is an empty pack (i.e. <>). Why is that? I thought given the argument list (1.0, 1, 2, 3), U would be deduced to int and Tn... would be double, int, int. What are the rules here for the type deduction?

If I changes the caller to:

valid<double, int, int>(1.0, 1, 2, 3);

It works. However, if I change it to:

valid<double, int, int, int>(1.0, 1, 2, 3);

It fails:

<source>:2:6: note:   template argument deduction/substitution failed:
<source>:5:33: note:   candidate expects 5 arguments, 4 provided
    5 |     valid<double, int, int, int>(1.0, 1, 2, 3);
      |     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~

What rules are used here to determine what types I can specify in the type parameter list?

Thanks.

C++ pointer function and new keyword

Good Day,

I usually find it best to look at other people's code when I try to learn a programming language.

I am now trying to learn C++ but having some trouble understanding the following function (as an example):

Vehicle* MyClass::GetVehicleByID(uint id)
{
    Vehicle* car = new Vehicle;
    car->model = vehiclesArray[id].model;
    return car;
}

int main()
{
    Vehicle* car = myClass.GetVehicleID(0);
    std::cout << "Car Model: " << car->model << std::endl;
}

I think I understand the concept of pointers. But I don't understand when this object will be destroyed. Will I have to manually delete the object "car" in the main function? Also, why are we using the new keyword instead of just using "Vehicle car();"? As I understand it the new keyword will allocate memory before populating it with the object?

Am I completely out of my depth just by asking these questions? Where or how can I learn to understand what is going on in this code? Because it seems like all tutorials only explain the "basics" like what a pointer is and the most basic way of using them.

Any help would be much appreciated.

Thread safety of std::cout insertion operator

I've always thought that using std::cout << something was thread safe.

For this little example

#include <iostream>
#include <thread>

void f()
{
   std::cout << "Hello from f\n";
}

void g()
{
   std::cout << "Hello from g\n";
}

int main()
{
   std::thread t1(f);
   std::thread t2(g);
   t1.join();
   t2.join();
}

my expectation was that the order of the two outputs would be undefined (and indeed that is what I observe in practice), but that the calls to operator<< are thread safe.

However, ThreadSanitizer, DRD and Helgrind all seem to give various errors regarding access to std::__1::ios_base::width(long) and std::__1::basic_ios<char, std::__1::char_traits >::fill()

On Compiler Explorer I don't see any errors.

On FreeBSD 13, ThreadSanitizer gives me 3 warnings, the two listed above plus the malloc/memcpy to the underlying i/o buffer.

Again in FreeBSD 13, DRD gives 4 errors, width() and fill() times two for the two threads.

Finally FreeBSD 13 Helgrind gives one known false positive related to TLS in thread creation, fill()and ẁidth()` twice.

On Fedora 34

  • No errors with g++ 11.2.1 and ThreadSanitizer
  • DRD complains about malloc/memcpy in fwrite with g++ compiled exe
  • Helgrind also complains about fwrite and also for the construction of cout, again with the g++ compiled exe
  • clang++ 12 ThreadSanitizer complains about fill() and width()
  • DRD with the clang++ compiler exe complains about fill(), width(), fwrite and one other in start_thread
  • Helgrind with the clang++ exe complains about some TLS, fill(), width(), fwrite

Looking at the libc++ and libstdc++ code I don't see anything at all that protects width(). So I don't understand why there are no complaints on compiler explorer.

Is there a way with tsan to either see the suppresions that are being used or to ignore default suppressions (assuming that there are some default suppressions)?

samedi 27 novembre 2021

C++ Adresses line don't show up entirly when I try to read from file, Why?

I'm trying to read from one file which contains around 4000 fictional people. Looks like this in the reading file but with many more people following.

Justin Biber 
199403012345
London second street 12 33444, Miami

my task was to swap the names with the last name to look like this...

Lastname Firstname [M] //  Male  // Part one 
Bieber     Justin     // Part two 
London second street 12 33444, Miami  // part three

I have succeeded to solve part One and part Two but not part Three parts out of three. Some of the addresses from the reading file contain more lines and street names than I expected, I don't know how to handle it. For example, look at these two addresses examples...

Lastname Firstname [M] //  Male  // Part one 
Bieber     Justin     // Part two 
London second street 12 33444, Miami  // part three


Lastname Firstname [F] // female  // Part one
Roberts Julia  // Part Two
London second street 13 33676, lontime ev second  // Part Three 

As you can see the second address is longer. I guess my question is. How can I read the entire line no matter how long the addresses are?

This is my code...

Note: I have solved Part One and Two, However for the address part, I do not know how to get the whole line.

#include <iostream>
#include <iomanip>
#include <fstream>
#include <climits>
#include <string>
#include <sstream> 
#include <algorithm>
#include <vector>

std::string swap_first_last_name(std::string first_name, std::string last_name){  // Swap function
    std::string swap_names{};
    swap_names = first_name;
    first_name = last_name;
    last_name = swap_names;
    return swap_names;
}

int main(){
 std::ifstream input; 
 std::ofstream output;  


 input.open("labb-2.txt");  // 
 if(!input){
  std::cerr << "The file failed to be loaded" << std::endl;
  // std::exit(EXIT_FAILURE);
return 1; // Exit the program
 }



  output.open("output.txt");  // skriv ut resultatet i en annan fil.
 if(!output){
  std::cerr << "The file failed to be loaded" << std::endl;
  // std::exit(EXIT_FAILURE);
return 1; // Exit the program
 }

// All my variables
std::string  first_name{}, last_name{};
const int field_width {10};
const int field1_width {5};
const int field2_width {20};
std::string persoonalnumber{};
std::string adress{};




while( input >> last_name >> first_name >> persoonalnumber >> adress) {
  // // look if the person is male or female. 
   char per =   persoonalnumber[ persoonalnumber.length() - 2];  // find the second last 
      character from the string
   std::string man_eller_kvinna =  (per % 2 == 1) ? "[M]" : "[K]";  // Tenary operator  ? :
   output << std::setw(field2_width) << std::left <<  "Lastname," 
   << std::setw(15) << "Firstname" << std::setw(field_width)  <<  man_eller_kvinna;

  // output << std::setw(field2_width)<< std::left <<  persoonalnumber<< std::endl; 

 output << std::endl;  // new line

  // Swap the first_name with the last_name
  output << std::setw(field2_width)<< std::left << first_name
  << std::setw(field1_width)  << last_name << std::endl;
  swap_first_last_name(last_name, first_name);  // call the function
  // first_name.swap(last_name);
  output << std::endl;


// Part three addresses, I don't know what to do! 


   output << std::endl;


      
          
           
}

 std::cout << std::endl;  // Give me new lines with finish message 
 std::cout << "File transformation is Done!" << std::endl;
 std::cout << std::endl;

 input.close();
 output.close();

 return 0;
}


How to copy a character from basic string into a vector string?

//Defining the class

class Hangman
{
    private:
        vector<string> dictionary;          //stores all the words
        vector<string> secretWord;          //stores the secret word
        vector<string> misses;              //keeps record of wrong guesses
        vector<string> displayVector;           //Stores "_"
        string originalWord;                //stores a copy of secret word to display at the 
end of game.
        bool gameOver = false;                      //Flag to check if the player lost or 
still in the game.
        int totalAttempts;
            
    public:                                 
    void selectRandWord();                      
};

//This is the function i am having problem in.

void Hangman::selectRandWord()
{
    secretWord.clear();

//word is a basic string that stores a random word. lets say "Hello World".

    string word;
    srand(time(NULL)); 
    int random = (rand() % dictionary.size()) + 1;

//I store a random word from vector to word.

    word = dictionary[random];
    transform(word.begin(), word.end(), word.begin(), ::tolower);           
    originalWord = word;
    for (int index = 0; index < word.length(); index++) 
    { 

//This line has the error: [Error] invalid user-defined conversion from 'char' to 'std::vectorstd::basic_string<char >::value_type&& {aka std::basic_string&&}' [-fpermissive]

//What I am trying to do is take each character from word(for example: "H") and push it back into the vector string secretWord.

        secretWord.push_back(word[index]); 
    } 
}

Deleting all nodes inside a linked list

I've created this function, and I'm wanting to delete all of the nodes inside of the linked list. However, it doesn't seem to be working and only deletes the first node (?).

void deleteList(Node* &pTemp) {
    Node *pCurrent = pTemp;
    Node* next = NULL;

    while(pCurrent != NULL) {
        next = pCurrent -> nextNode;
        free(pCurrent);
        pCurrent = next;
    }
}

What can I do to make this delete every single node, but still have an empty list?

Is there a way to delete from a set and move the value to a temporary?

Is there a way to delete an item in a set / map and get the former value as a temporary return value so that I can move() somewhere else ?

How to achieve that a thread in multithreading ends first, and the main thread continues to execute

I try to implement a function: the primary thread creates multiple sub-threads and blocks the primary thread, and wakes up the primary thread to continue execution when any of the sub-threads ends. The following code is my attempt to use std::future in C++11:

std::pair<size_t, size_t> fun(size_t i, size_t j)
{
    std::this_thread::sleep_for(std::chrono::seconds(i * j));
    return { i, j };
}

int main()
{
    std::shared_future<std::pair<size_t, size_t>> ret;
    std::pair<size_t, size_t> temp;

    ret = std::async(fun, 10, 9);
    ret = std::async(fun, 5, 4);
    ret = std::async(fun, 2, 1);
    temp = ret.get();
    std::cout << temp.first << "\t" << temp.second << "\n";

    return 0;
}

For the result, I hope the program will directly output "2 1" after (2 * 1) seconds and end the primary thread, but in my attempt, the program needs to wait for the first sub-thread to sleep for (10 * 9) seconds before outputting "2 1" and end the primary thread.

Thanks in advance!

vendredi 26 novembre 2021

Leaving Only Unique Specific Words(technically Sentences) [closed]

Greetings Sires and Dams, I have a some trouble here. Let's say I have a some Structure(let's call it Text) that including a Specific Words'. These Specific Words is actually a different Sentences here. Also these Specific Words in this Text, as intended(but it is not necessary), are indicated by a ';;;' sign on both sides like this one: ';;;A;;;', and they are divided by only single Space like this:

  • "';;;A;;;' ';;;B;;;'";

these Words can also have Space inside of them(because they're actually a sentences) and other punctuation marks, like this:

  • "';;;Something is written here, but I couldn't see this;;;' ';;;Can I take this cookie on your desk? No? It's so much sad;;;'";

so, we can describe this Text like:

  • ";;;A;;; ;;;B;;; ;;;D;;; ;;;C;;; ;;;A;;; ;;;D;;;";
  • ";;;B;;; ;;;D;;; ;;;A;;; ;;;D;;;";
  • ";;;A;;; ;;;B;;; ;;;D;;;";
  • ";;;A;;; ;;;B;;;";
  • ";;;C;;; ;;;A;;; ;;;D;;;";

and etc.

{';'<--end of line, '"X"' is for Line, ';', and '"' is used here just as element of design for simplify distinction between other signs, and for better description of my thoughts, this is can be seemed only by humans, not by compiler}

So, like I say earlier this is Text and it have a Certain Structure and if we can carry out a certain Operations by it we need to preserve it in the end.

Lastly, I have a question:

  • Is there certain Operations that can Leave only Unique Words in this Text?

like this:

  • ";;;A;;; ;;;B;;; ;;;D;;; ;;;C;;;'LE''LE'";
  • "'LE''LE''LE''LE'";
  • "'LE''LE''LE'";
  • "'LE''LE'";
  • "'LE''LE''LE'";

and etc.

{'LE' is for 'Leave Empty'}

I would like to do it in Notepad++, but if there are any other options to do it that'll be a great to know more about them. I also will be glad to hear about any other solutions of this problem.

Thanks whoever for reading this. And I thanks in advance whoever dared to help me. Thank you twice.

Boost transformed conversion to vector error

I am new to using boost adapters, I am using the following code for conversion of a vector one class to transformed version.

The return type of boost::transformed is not as per expectation. Can someone please illuminate as to what I am missing here:

class blabla
{
    public:
    int x;
};

class blabla2
{
    public:
    int  y;
    blabla2(int a)
    {
        y=a;
    }
};


int main()
{
    using namespace boost::adaptors;
    std::vector<blabla> test;

    auto foo = [](const blabla& A) -> std::pair<blabla2, double> {
        return std::make_pair(blabla2(A.x), double(A.x));
    };

    const auto histogram = test | boost::adaptors::transformed(foo);
    // std::vector<std::pair<blabla2, double>> should be return type? 

    std::vector<std::pair<blabla2, double>> histogramtest = histogram; ----> this line gives error unexpectedly. Why is it so?
    std::pair<blabla2, double> x = histogram[0];
}

The line std::vector<std::pair<blabla2, double>> histogramtest = histogram; gives error

While std::pair<blabla2, double> x = histogram[0]; works correctly. Why is that so?

CMake can't link a custom library

I'm building a game with raylib and made my own custom button in different files to reuse it when I need it.

I watched tons of videos and read docs but I don't know why it throws undefined reference to CustomButton::CustomButton().

Here's the error:

/usr/bin/ld: CMakeFiles/AstroX.dir/src/main.cpp.o: in function `_GLOBAL__sub_I_main':
main.cpp:(.text.startup+0xaca): undefined reference to `CustomButton::CustomButton(Vector2, float, Texture2D, char const*, int, Color)'
collect2: error: ld returned 1 exit status
make[2]: *** [CMakeFiles/AstroX.dir/build.make:105: AstroX] Error 1
make[1]: *** [CMakeFiles/Makefile2:153: CMakeFiles/AstroX.dir/all] Error 2
make: *** [Makefile:156: all] Error 2

Here's my folder structure:

Folder Structure

My CMakeLists.txt:

cmake_minimum_required(VERSION 3.0)

project(AstroX VERSION 1.0.0)

set(CMAKE_CXX_STANDARD 17)

# Setting parameters for raylib
set(BUILD_EXAMPLES OFF CACHE BOOL "" FORCE) # don't build the supplied examples
set(BUILD_GAMES    OFF CACHE BOOL "" FORCE) # or games


add_library(
    custom_button
    src/custom_button.cpp
    src/custom_button.hpp
)
    
add_subdirectory(libs/raylib)

add_executable(${PROJECT_NAME} src/main.cpp)

target_link_libraries(AstroX PRIVATE custom_button)

target_link_libraries(${PROJECT_NAME} PRIVATE raylib)

Here's my custom_button.hpp:

#ifndef BUTTON_INCLUDED

#define BUTTON_INCLUDED
#include "raylib.h"

class CustomButton {
    public:

        // Position and the size of the button
        Vector2 position;   // position of the button (x,y)
        float scale;        // scale of the button

        // Texture and Text inside it
        Texture2D texture;  // texture of the button
        const char* text;   // text of the button (placed in the middle of the button)
        int fontSize;       // font size of the text
        Color textColor;    // color of the text

        // Constructor
        CustomButton(Vector2 position, float scale, Texture2D texture, const char* text, int fontSize, Color textColor);

        // State getters
        bool isHovered();   // check if the mouse is hovering over the button
        bool isClicked();   // check if the button is clicked

};

#endif

My custom_button.cpp:

#include "custom_button.hpp"

CustomButton::CustomButton(Vector2 position, float scale, Texture2D texture, const char* text, int fontSize, Color textColor) {
    this->position = position;
    this->scale = scale;
    this->texture = texture;
    this->text = text;
    this->fontSize = fontSize;
    this->textColor = textColor;
}

bool CustomButton::isHovered() {
    Vector2 mouse_location = GetMousePosition();
    if (mouse_location.x > position.x && mouse_location.x < position.x + texture.width * scale &&
        mouse_location.y > position.y && mouse_location.y < position.y + texture.height * scale) {
        return true;
    }
    return false;
}

bool CustomButton::isClicked() {
    if (isHovered()) {
        if (IsMouseButtonPressed(MOUSE_LEFT_BUTTON)) {
            return true;
        }
    }
    return false;
}

And finally my main.cpp:

#include "raylib.h"
#include <string>
#include <math.h>

#include "custom_button.hpp"

#define PLAYER_SIZE  0.2f
#define PLAYER_SPEED 6.0f
#define PLAYER_ACCELERATION 0.5f
#define PLAYER_MAX_ACCELERATION 2.0f
#define DRAG 0.04f


//------
// Types
//------
struct Player {
    Vector2 position;
    Vector2 speed;
    float acceleration;
    float rotation;
};

//--------
// Globals
//--------
static const int screenWidth = 1000;
static const int screenHeight = 800;

static bool gameOver = false;
static bool pause = false;
static bool victory = false;

static float shipHeight = 0.0f;

static Player player = { 0 };
static Texture2D playerTexture;

static Texture2D btnTexture;
static CustomButton btnPlay = CustomButton(Vector2{ screenWidth / 2, screenHeight / 2 }, 0.5f, btnTexture, "Play", 20, WHITE );

static void InitGame();         // Initialize game
static void UpdateGame();       // Update game (one frame)
static void DrawGame();         // Draw game (one frame)
static void UnloadGame();       // Unload game
static void UpdateDrawFrame();  // Update and Draw (one frame)

int main()
{
    InitWindow(screenWidth, screenHeight, "AstroX");
    SetTargetFPS(60);
    InitGame();

    while (!WindowShouldClose())
    {
        UpdateDrawFrame();
    }

    UnloadGame();        
    CloseWindow(); 

    return 0;
}

//-----------
// Functions
//-----------

// Initialize game variables
void InitGame()
{
    bool correctRange = false;
    victory = false;
    pause = false;

    shipHeight = (playerTexture.height * PLAYER_SIZE) / tanf(20*DEG2RAD);

    // Initialization player
    playerTexture = LoadTexture("/home/d3r1n/Desktop/Projects/AstroX/assets/Spaceship.png");
    player.position = Vector2 {screenWidth/2 - (float) playerTexture.width * PLAYER_SIZE, screenHeight / 2 - (float) playerTexture.height * PLAYER_SIZE};
    player.speed = Vector2 {0, 0};
    player.acceleration = 0;
    player.rotation = 0;
}

// Update game (one frame)
void UpdateGame(void)
{
    if (!gameOver)
    {
        if (IsKeyPressed('P')) pause = !pause;

        if (!pause)
        {
            // Player logic: rotation
            if (IsKeyDown(KEY_LEFT)) player.rotation -= 5;
            if (IsKeyDown(KEY_RIGHT)) player.rotation += 5;
            if (player.rotation > 360) player.rotation -= 360;
            if (player.rotation < -360) player.rotation += 360;

            // Player logic: speed
            player.speed.x = sin(player.rotation*DEG2RAD)*PLAYER_SPEED;
            player.speed.y = cos(player.rotation*DEG2RAD)*PLAYER_SPEED;

            // Player logic: acceleration
            if (IsKeyDown(KEY_UP))
            {
                if (player.acceleration < PLAYER_MAX_ACCELERATION) player.acceleration += PLAYER_ACCELERATION;
            }
            else
            {
                if (player.acceleration > 0) player.acceleration -= DRAG;
                else if (player.acceleration < 0) player.acceleration = 0;
            }
            if (IsKeyDown(KEY_DOWN))
            {
                if (player.acceleration > 0) player.acceleration -= PLAYER_ACCELERATION / 2;
                else if (player.acceleration < 0) player.acceleration = 0;
            }

            // Player logic: movement
            player.position.x += (player.speed.x * player.acceleration);
            player.position.y -= (player.speed.y * player.acceleration);

            // Collision logic: player vs walls
            if (player.position.x > screenWidth + shipHeight) player.position.x = -(shipHeight);
            else if (player.position.x < -(shipHeight)) player.position.x = screenWidth + shipHeight;
            if (player.position.y > (screenHeight + shipHeight)) player.position.y = -(shipHeight);
            else if (player.position.y < -(shipHeight)) player.position.y = screenHeight + shipHeight;
        }
    }
    else
    {
        if (IsKeyPressed(KEY_ENTER))
        {
            InitGame();
            gameOver = false;
        }
    }
}

// Draw game (one frame)
void DrawGame()
{
    BeginDrawing();

        ClearBackground(RAYWHITE);

        if (!gameOver)
        {
            // Draw player
            DrawTexturePro(
                playerTexture, 
                Rectangle {1, 1, (float)playerTexture.width, (float)playerTexture.height}, 
                Rectangle {player.position.x, player.position.y, (float)playerTexture.width * PLAYER_SIZE, (float)playerTexture.height * PLAYER_SIZE}, 
                Vector2 {(float)playerTexture.width * PLAYER_SIZE / 2, (float)playerTexture.height * PLAYER_SIZE / 2}, 
                player.rotation,
                WHITE
            );

        
            // Draw FPS
            DrawText("FPS:", 10, 10, 20, BLACK);
            DrawText(std::to_string(GetFPS()).c_str(), MeasureText("FPS:", 20) + 20, 10, 20, GREEN);
            
            // Draw player acceleration
            DrawText("Acceleration:", 10, 30, 20, BLACK);
            DrawText(std::to_string(player.acceleration).c_str(), MeasureText("Acceleration:", 20) + 20, 30, 20, BLACK);

            // Draw player rotation
            DrawText("Rotation:", 10, 50, 20, BLACK);
            DrawText(std::to_string(player.rotation).c_str(), MeasureText("Rotation:", 20) + 20, 50, 20, BLACK);
        }
        else
        {
            DrawText("Game Over!", screenWidth/2 - MeasureText("Game Over!", 30)/2, screenHeight/2 - 30, 30, RED);
            DrawText("Press ENTER to restart", screenWidth/2 - MeasureText("Press ENTER to restart", 20)/2, screenHeight/2 + 30, 20, RED);
        }

        if (!gameOver)
        {

            if (victory) DrawText("VICTORY", screenWidth/2 - MeasureText("VICTORY", 20)/2, screenHeight/2, 20, LIGHTGRAY);

            if (pause) {
                DrawText("GAME PAUSED", screenWidth/2 - MeasureText("GAME PAUSED", 40)/2, screenHeight/2 - 40, 40, Color{150, 150, 150, 255});
            }
        }
        else {
            DrawText("PRESS [ENTER] TO PLAY AGAIN", GetScreenWidth()/2 - MeasureText("PRESS [ENTER] TO PLAY AGAIN", 20)/2, GetScreenHeight()/2 - 50, 20, GRAY);
        }

    EndDrawing();
}

// Unload game variables
void UnloadGame()
{
    // TODO: Unload all dynamic loaded data (textures, sounds, models...)
}

// Update and Draw (one frame)
void UpdateDrawFrame()
{
    UpdateGame();
    DrawGame();
}

Verbose Output (cmake --build . --verbose) :

/usr/bin/cmake -S/home/d3r1n/Desktop/Projects/AstroX -B/home/d3r1n/Desktop/Projects/AstroX/build --check-build-system CMakeFiles/Makefile.cmake 0
/usr/bin/cmake -E cmake_progress_start /home/d3r1n/Desktop/Projects/AstroX/build/CMakeFiles /home/d3r1n/Desktop/Projects/AstroX/build//CMakeFiles/progress.marks
/usr/bin/make  -f CMakeFiles/Makefile2 all
make[1]: Entering directory '/home/d3r1n/Desktop/Projects/AstroX/build'
/usr/bin/make  -f libs/raylib/src/external/glfw/src/CMakeFiles/glfw_objlib.dir/build.make libs/raylib/src/external/glfw/src/CMakeFiles/glfw_objlib.dir/depend
make[2]: Entering directory '/home/d3r1n/Desktop/Projects/AstroX/build'
cd /home/d3r1n/Desktop/Projects/AstroX/build && /usr/bin/cmake -E cmake_depends "Unix Makefiles" /home/d3r1n/Desktop/Projects/AstroX /home/d3r1n/Desktop/Projects/AstroX/libs/raylib/src/external/glfw/src /home/d3r1n/Desktop/Projects/AstroX/build /home/d3r1n/Desktop/Projects/AstroX/build/libs/raylib/src/external/glfw/src /home/d3r1n/Desktop/Projects/AstroX/build/libs/raylib/src/external/glfw/src/CMakeFiles/glfw_objlib.dir/DependInfo.cmake --color=
Dependencies file "libs/raylib/src/external/glfw/src/CMakeFiles/glfw_objlib.dir/context.c.o.d" is newer than depends file "/home/d3r1n/Desktop/Projects/AstroX/build/libs/raylib/src/external/glfw/src/CMakeFiles/glfw_objlib.dir/compiler_depend.internal".
Dependencies file "libs/raylib/src/external/glfw/src/CMakeFiles/glfw_objlib.dir/egl_context.c.o.d" is newer than depends file "/home/d3r1n/Desktop/Projects/AstroX/build/libs/raylib/src/external/glfw/src/CMakeFiles/glfw_objlib.dir/compiler_depend.internal".
Dependencies file "libs/raylib/src/external/glfw/src/CMakeFiles/glfw_objlib.dir/glx_context.c.o.d" is newer than depends file "/home/d3r1n/Desktop/Projects/AstroX/build/libs/raylib/src/external/glfw/src/CMakeFiles/glfw_objlib.dir/compiler_depend.internal".
Dependencies file "libs/raylib/src/external/glfw/src/CMakeFiles/glfw_objlib.dir/init.c.o.d" is newer than depends file "/home/d3r1n/Desktop/Projects/AstroX/build/libs/raylib/src/external/glfw/src/CMakeFiles/glfw_objlib.dir/compiler_depend.internal".
Dependencies file "libs/raylib/src/external/glfw/src/CMakeFiles/glfw_objlib.dir/input.c.o.d" is newer than depends file "/home/d3r1n/Desktop/Projects/AstroX/build/libs/raylib/src/external/glfw/src/CMakeFiles/glfw_objlib.dir/compiler_depend.internal".
Dependencies file "libs/raylib/src/external/glfw/src/CMakeFiles/glfw_objlib.dir/linux_joystick.c.o.d" is newer than depends file "/home/d3r1n/Desktop/Projects/AstroX/build/libs/raylib/src/external/glfw/src/CMakeFiles/glfw_objlib.dir/compiler_depend.internal".
Dependencies file "libs/raylib/src/external/glfw/src/CMakeFiles/glfw_objlib.dir/monitor.c.o.d" is newer than depends file "/home/d3r1n/Desktop/Projects/AstroX/build/libs/raylib/src/external/glfw/src/CMakeFiles/glfw_objlib.dir/compiler_depend.internal".
Dependencies file "libs/raylib/src/external/glfw/src/CMakeFiles/glfw_objlib.dir/osmesa_context.c.o.d" is newer than depends file "/home/d3r1n/Desktop/Projects/AstroX/build/libs/raylib/src/external/glfw/src/CMakeFiles/glfw_objlib.dir/compiler_depend.internal".
Dependencies file "libs/raylib/src/external/glfw/src/CMakeFiles/glfw_objlib.dir/posix_thread.c.o.d" is newer than depends file "/home/d3r1n/Desktop/Projects/AstroX/build/libs/raylib/src/external/glfw/src/CMakeFiles/glfw_objlib.dir/compiler_depend.internal".
Dependencies file "libs/raylib/src/external/glfw/src/CMakeFiles/glfw_objlib.dir/posix_time.c.o.d" is newer than depends file "/home/d3r1n/Desktop/Projects/AstroX/build/libs/raylib/src/external/glfw/src/CMakeFiles/glfw_objlib.dir/compiler_depend.internal".
Dependencies file "libs/raylib/src/external/glfw/src/CMakeFiles/glfw_objlib.dir/vulkan.c.o.d" is newer than depends file "/home/d3r1n/Desktop/Projects/AstroX/build/libs/raylib/src/external/glfw/src/CMakeFiles/glfw_objlib.dir/compiler_depend.internal".
Dependencies file "libs/raylib/src/external/glfw/src/CMakeFiles/glfw_objlib.dir/window.c.o.d" is newer than depends file "/home/d3r1n/Desktop/Projects/AstroX/build/libs/raylib/src/external/glfw/src/CMakeFiles/glfw_objlib.dir/compiler_depend.internal".
Dependencies file "libs/raylib/src/external/glfw/src/CMakeFiles/glfw_objlib.dir/x11_init.c.o.d" is newer than depends file "/home/d3r1n/Desktop/Projects/AstroX/build/libs/raylib/src/external/glfw/src/CMakeFiles/glfw_objlib.dir/compiler_depend.internal".
Dependencies file "libs/raylib/src/external/glfw/src/CMakeFiles/glfw_objlib.dir/x11_monitor.c.o.d" is newer than depends file "/home/d3r1n/Desktop/Projects/AstroX/build/libs/raylib/src/external/glfw/src/CMakeFiles/glfw_objlib.dir/compiler_depend.internal".
Dependencies file "libs/raylib/src/external/glfw/src/CMakeFiles/glfw_objlib.dir/x11_window.c.o.d" is newer than depends file "/home/d3r1n/Desktop/Projects/AstroX/build/libs/raylib/src/external/glfw/src/CMakeFiles/glfw_objlib.dir/compiler_depend.internal".
Dependencies file "libs/raylib/src/external/glfw/src/CMakeFiles/glfw_objlib.dir/xkb_unicode.c.o.d" is newer than depends file "/home/d3r1n/Desktop/Projects/AstroX/build/libs/raylib/src/external/glfw/src/CMakeFiles/glfw_objlib.dir/compiler_depend.internal".
Consolidate compiler generated dependencies of target glfw_objlib
make[2]: Leaving directory '/home/d3r1n/Desktop/Projects/AstroX/build'
/usr/bin/make  -f libs/raylib/src/external/glfw/src/CMakeFiles/glfw_objlib.dir/build.make libs/raylib/src/external/glfw/src/CMakeFiles/glfw_objlib.dir/build
make[2]: Entering directory '/home/d3r1n/Desktop/Projects/AstroX/build'
make[2]: Nothing to be done for 'libs/raylib/src/external/glfw/src/CMakeFiles/glfw_objlib.dir/build'.
make[2]: Leaving directory '/home/d3r1n/Desktop/Projects/AstroX/build'
[ 55%] Built target glfw_objlib
/usr/bin/make  -f libs/raylib/src/external/glfw/src/CMakeFiles/glfw.dir/build.make libs/raylib/src/external/glfw/src/CMakeFiles/glfw.dir/depend
make[2]: Entering directory '/home/d3r1n/Desktop/Projects/AstroX/build'
cd /home/d3r1n/Desktop/Projects/AstroX/build && /usr/bin/cmake -E cmake_depends "Unix Makefiles" /home/d3r1n/Desktop/Projects/AstroX /home/d3r1n/Desktop/Projects/AstroX/libs/raylib/src/external/glfw/src /home/d3r1n/Desktop/Projects/AstroX/build /home/d3r1n/Desktop/Projects/AstroX/build/libs/raylib/src/external/glfw/src /home/d3r1n/Desktop/Projects/AstroX/build/libs/raylib/src/external/glfw/src/CMakeFiles/glfw.dir/DependInfo.cmake --color=
make[2]: Leaving directory '/home/d3r1n/Desktop/Projects/AstroX/build'
/usr/bin/make  -f libs/raylib/src/external/glfw/src/CMakeFiles/glfw.dir/build.make libs/raylib/src/external/glfw/src/CMakeFiles/glfw.dir/build
make[2]: Entering directory '/home/d3r1n/Desktop/Projects/AstroX/build'
make[2]: Nothing to be done for 'libs/raylib/src/external/glfw/src/CMakeFiles/glfw.dir/build'.
make[2]: Leaving directory '/home/d3r1n/Desktop/Projects/AstroX/build'
[ 58%] Built target glfw
/usr/bin/make  -f CMakeFiles/custom_button.dir/build.make CMakeFiles/custom_button.dir/depend
make[2]: Entering directory '/home/d3r1n/Desktop/Projects/AstroX/build'
cd /home/d3r1n/Desktop/Projects/AstroX/build && /usr/bin/cmake -E cmake_depends "Unix Makefiles" /home/d3r1n/Desktop/Projects/AstroX /home/d3r1n/Desktop/Projects/AstroX /home/d3r1n/Desktop/Projects/AstroX/build /home/d3r1n/Desktop/Projects/AstroX/build /home/d3r1n/Desktop/Projects/AstroX/build/CMakeFiles/custom_button.dir/DependInfo.cmake --color=
Dependencies file "CMakeFiles/custom_button.dir/src/custom_button.cpp.o.d" is newer than depends file "/home/d3r1n/Desktop/Projects/AstroX/build/CMakeFiles/custom_button.dir/compiler_depend.internal".
Consolidate compiler generated dependencies of target custom_button
make[2]: Leaving directory '/home/d3r1n/Desktop/Projects/AstroX/build'
/usr/bin/make  -f CMakeFiles/custom_button.dir/build.make CMakeFiles/custom_button.dir/build
make[2]: Entering directory '/home/d3r1n/Desktop/Projects/AstroX/build'
make[2]: Nothing to be done for 'CMakeFiles/custom_button.dir/build'.
make[2]: Leaving directory '/home/d3r1n/Desktop/Projects/AstroX/build'
[ 65%] Built target custom_button
/usr/bin/make  -f libs/raylib/src/CMakeFiles/raylib_static.dir/build.make libs/raylib/src/CMakeFiles/raylib_static.dir/depend
make[2]: Entering directory '/home/d3r1n/Desktop/Projects/AstroX/build'
cd /home/d3r1n/Desktop/Projects/AstroX/build && /usr/bin/cmake -E cmake_depends "Unix Makefiles" /home/d3r1n/Desktop/Projects/AstroX /home/d3r1n/Desktop/Projects/AstroX/libs/raylib/src /home/d3r1n/Desktop/Projects/AstroX/build /home/d3r1n/Desktop/Projects/AstroX/build/libs/raylib/src /home/d3r1n/Desktop/Projects/AstroX/build/libs/raylib/src/CMakeFiles/raylib_static.dir/DependInfo.cmake --color=
Dependencies file "libs/raylib/src/CMakeFiles/raylib_static.dir/core.c.o.d" is newer than depends file "/home/d3r1n/Desktop/Projects/AstroX/build/libs/raylib/src/CMakeFiles/raylib_static.dir/compiler_depend.internal".
Dependencies file "libs/raylib/src/CMakeFiles/raylib_static.dir/models.c.o.d" is newer than depends file "/home/d3r1n/Desktop/Projects/AstroX/build/libs/raylib/src/CMakeFiles/raylib_static.dir/compiler_depend.internal".
Dependencies file "libs/raylib/src/CMakeFiles/raylib_static.dir/raudio.c.o.d" is newer than depends file "/home/d3r1n/Desktop/Projects/AstroX/build/libs/raylib/src/CMakeFiles/raylib_static.dir/compiler_depend.internal".
Dependencies file "libs/raylib/src/CMakeFiles/raylib_static.dir/shapes.c.o.d" is newer than depends file "/home/d3r1n/Desktop/Projects/AstroX/build/libs/raylib/src/CMakeFiles/raylib_static.dir/compiler_depend.internal".
Dependencies file "libs/raylib/src/CMakeFiles/raylib_static.dir/text.c.o.d" is newer than depends file "/home/d3r1n/Desktop/Projects/AstroX/build/libs/raylib/src/CMakeFiles/raylib_static.dir/compiler_depend.internal".
Dependencies file "libs/raylib/src/CMakeFiles/raylib_static.dir/textures.c.o.d" is newer than depends file "/home/d3r1n/Desktop/Projects/AstroX/build/libs/raylib/src/CMakeFiles/raylib_static.dir/compiler_depend.internal".
Dependencies file "libs/raylib/src/CMakeFiles/raylib_static.dir/utils.c.o.d" is newer than depends file "/home/d3r1n/Desktop/Projects/AstroX/build/libs/raylib/src/CMakeFiles/raylib_static.dir/compiler_depend.internal".
Consolidate compiler generated dependencies of target raylib_static
make[2]: Leaving directory '/home/d3r1n/Desktop/Projects/AstroX/build'
/usr/bin/make  -f libs/raylib/src/CMakeFiles/raylib_static.dir/build.make libs/raylib/src/CMakeFiles/raylib_static.dir/build
make[2]: Entering directory '/home/d3r1n/Desktop/Projects/AstroX/build'
make[2]: Nothing to be done for 'libs/raylib/src/CMakeFiles/raylib_static.dir/build'.
make[2]: Leaving directory '/home/d3r1n/Desktop/Projects/AstroX/build'
[ 93%] Built target raylib_static
/usr/bin/make  -f CMakeFiles/AstroX.dir/build.make CMakeFiles/AstroX.dir/depend
make[2]: Entering directory '/home/d3r1n/Desktop/Projects/AstroX/build'
cd /home/d3r1n/Desktop/Projects/AstroX/build && /usr/bin/cmake -E cmake_depends "Unix Makefiles" /home/d3r1n/Desktop/Projects/AstroX /home/d3r1n/Desktop/Projects/AstroX /home/d3r1n/Desktop/Projects/AstroX/build /home/d3r1n/Desktop/Projects/AstroX/build /home/d3r1n/Desktop/Projects/AstroX/build/CMakeFiles/AstroX.dir/DependInfo.cmake --color=
Dependencies file "CMakeFiles/AstroX.dir/src/main.cpp.o.d" is newer than depends file "/home/d3r1n/Desktop/Projects/AstroX/build/CMakeFiles/AstroX.dir/compiler_depend.internal".
Consolidate compiler generated dependencies of target AstroX
make[2]: Leaving directory '/home/d3r1n/Desktop/Projects/AstroX/build'
/usr/bin/make  -f CMakeFiles/AstroX.dir/build.make CMakeFiles/AstroX.dir/build
make[2]: Entering directory '/home/d3r1n/Desktop/Projects/AstroX/build'
[ 96%] Linking CXX executable AstroX
/usr/bin/cmake -E cmake_link_script CMakeFiles/AstroX.dir/link.txt --verbose=1
/usr/bin/c++ -O3 -DNDEBUG -rdynamic CMakeFiles/AstroX.dir/src/main.cpp.o -o AstroX  libcustom_button.a libs/raylib/src/libraylib.a libs/raylib/src/external/glfw/src/libglfw3.a -lrt -lm -ldl -lX11 -lpthread -lm -lpthread -lGL -lGLU 
/usr/bin/ld: CMakeFiles/AstroX.dir/src/main.cpp.o: in function `_GLOBAL__sub_I_main':
main.cpp:(.text.startup+0xaca): undefined reference to `CustomButton::CustomButton(Vector2, float, Texture2D, char const*, int, Color)'
collect2: error: ld returned 1 exit status
make[2]: *** [CMakeFiles/AstroX.dir/build.make:105: AstroX] Error 1
make[2]: Leaving directory '/home/d3r1n/Desktop/Projects/AstroX/build'
make[1]: *** [CMakeFiles/Makefile2:153: CMakeFiles/AstroX.dir/all] Error 2
make[1]: Leaving directory '/home/d3r1n/Desktop/Projects/AstroX/build'
make: *** [Makefile:156: all] Error 2

Copy elision and move constructor

Consider the following definition of Person:

struct Person
{
    Person() { std::cout << "construct, "; }
    Person(const Person&) { std::cout << "copy\n"; }
    Person(Person&&) { std::cout << "move\n"; }
};

And 3 different functions to create a Person:

Person create1()
{
    std::cout << "create1: ";
    Person p1{};
    return p1;
}

Person create2()
{
    std::cout << "create2: ";
    if constexpr (true)
    {
        Person p1{};
        return p1;
    }
    else
    {
        Person p2{};
        return p2;
    }
}
    
Person create3()
{
    std::cout << "create3: ";
    if constexpr (true)
    {
        return Person{};
    }
    else
    {
        return Person{};
    }
}

Finally, I call the create functions as follows:

int main()
{
    Person p1 = create1();
    Person p2 = create2();
    Person p3 = create3();
    return 0;
}

The output is:

create1: construct
create2: construct, move
create3: construct

What bothers me is the output of create2. If in create1 and create3, the move constructor is not called, why is it called in create2?

I am using GCC 12.0.0.

jeudi 25 novembre 2021

Is it possible for different

If I initialize several const char* variables in the following ways:

const char* myString1 = "string content 1";
const char* myString2 = "string content 2";
...

Since const char* is simply a pointer a specific char object, it does not contain any size or range information of the character array it is pointing to.

So, is it possible for two string literals to overlap each other? (The newly allocated overlap the old one)

By overlap, I mean the following behaviour;

// Continue from the code block above
std::cout << myString1 << std::endl;
std::cout << myString2 << std::endl;

It outputs

string costring content 2
string content 2

So the start of myString2 is somewhere in the middle of myString1.

How does C++/compiler avoid such problem?

If I change const char* to const char[], is it still the same?

Is it possible that `shared_ptr::use_count() == 0` and `shared_ptr::get() != nullptr`?

From the cppref:

Notes

An empty shared_ptr (where use_count() == 0) may store a non-null pointer accessible by get(), e.g. if it were created using the aliasing constructor.

Is it possible that shared_ptr::use_count() == 0 and shared_ptr::get() != nullptr?

Any example to illustrate that is true?

How do you write a function that returns a node which value corresponds to a value stored in a variable?

I stumbled across this question in an old textbook I bought ages ago, whilst strictly speaking it is not too difficult, I could not find a post here that simply answered this one question. As such I thought "Hey perhaps someone starting out might be confused about this", and so I put together the following code:

#include <iostream>

using namespace std;

// Structures
struct charNode {
    char Node;
    charNode *next;
};

// Functions
charNode* getCharNode(char c) {
    return ; //<----- Return Node Here 
}

SIGSEGV error when using REGEX compiling with Clang and musl library

I have the following function that works fine if the regular expresion is correct, but get a SIGSEGV otherwise when compiling with clang-9 and using musl 1.2. However, it works fine with clang and glibc, tho, but I need to used musl instead.

Could someone help me here?

` void CRuntimeCommandLine::LoadComplement(const multimap<std::string, std::string>& mapArguments) { // Find parameter multimap<string, string>::const_iterator iter; iter = mapArguments.find("Complement"); if(iter == mapArguments.end()) { // Only fatal. Statement is not initialized yet. Logger::fatal(Errors::RCMD_F005_MISSING_MANDATORY_PARAM, "Missing mandatory parameter --Complement"); } // regex expression for system_secret to be checked (Max 4Bytes, hexadecimal number in //lowe case letters and no 0x format) regex regexp("^[0-9a-f]{1,8}$");

    // regex_search that searches pattern regexp in the string mystr
    std::string s = iter->second.c_str();
    if (false == std::regex_search(s, regexp))
    {
        // Only fatal. Statement is not initialized yet.
        Logger::fatal(Errors::RCMD_F006_INVALID_VALUE, "Invalid --Complement=hexvalue value");
    }
    else
    {
        // get hexadecimal value
        (void)sscanf(s.c_str(), "%X", &(m_cmdParameters.complementValue));
    }

Why do I need Boost.SmartPtr for the C++ compiler that supports C++11 and later?

The boost C++ library is a famous sandbox for the language and Standard Library features that absorbed with each new version of the Standard C++. However boost components that eventually became a part of the Standard are still present in boost. One of the classic examples of said above are smart pointers. So why do I need Boost.SmartPtr for the C++ compiler that supports C++11 and later?

output map object where the value can be any data type

Trying to output a map object where the value can be any data type. Tried the following:

#include <iostream>
#include <unordered_map>
#include <any>

std::unordered_map<std::string, std::any> example = {
    {"first", 'A'},
    {"second", 2},
    {"third", 'C'}
};

std::ostream &operator<<(std::ostream &os,
                    const std::any &m) {
 for (auto &t : example) {
    os << "{" << t.first << ": " << t.second << "}\n";
}
return os;
}

 int main()
{std::cout << example;
 return 0;
}

But,getting infinite loop of values.

mercredi 24 novembre 2021

constexpr value defined in header file cased problem,how to solve it?

a.h
constexpr uint64_t seed = strhash_ct(__TIME__);
//seed in a.h must be constexpr,baseuse i want to put it in template,like this:
HashJic::ensure_compile_time<seed>::value

b.cpp
#include "a.h"
uint64_t b = seed;

c.cpp
#include "a.h"
uint64_t c = seed;

In this case b != c
How can i get the same value?

extra information 1:strhash_ct is a constexpr function

Overloading output operator is not working as intended

I'm trying to overload << to print the protected members of a class as a string, but when I try to use it in another class doing std::cout << player2; I get "0x7f60b0100" as output.

"player2" is an Actor*, so I'm not sure what's happening.

class Actor {

private:
    string type;
protected:
    int health;
    int damage;
    vector<MoveType> moves;

public:
    Actor(string type, int health): type{ type }, health{ health }{damage=0;}
    virtual void Hit(int damage){health = health-damage;}
    virtual void Heal(int amount){health=+amount;}
    const vector<MoveType>& GetMoves() const {return moves;}

    bool IsDead() { return health <= 0; }

    friend ostream& operator<<(ostream& out, const Actor& actor){
        return (out << "DAMAGE DONE: " << actor.damage << "HEALTH: "<< actor.health);
    }
};

Why is move-constructor not called?

I have the following piece of code:

#include <iostream>

struct T {
    int a;

    T() = default;

    T(T& other) {
        std::cout << "copy &\n";
    }

    T(T&& other) {
        std::cout << "move &&\n";
    }
};

void foo(T&& x) {
    T y(x); // why is copy ctor called??????
}

int main() {
    T x;
    foo(std::move(x));

    return 0;
}

I don't understand why copy constructor is preferred over move constructor even though foo() accepts rvalue-reference.

Why do

I was experimenting with C++ and found out that const char* and const char[] behave very differently with the following code. Really sorry if I did not phrase this question very well as I am not clear of what is happening in the code.

#include <iostream>                                                                                                        
#include <vector>                                                                                                          

// This version uses <const char[3]> for <myStr>.
// It does not work as expected.                                                                                                                      
struct StrStruct                                                                                                           
{                                                                                                                  
    const char myStr[3];                                                                                                     
};                                                                                                                         
       
// This program extracts all the string elements in <strStructList> and copy them to <strListCopy>                                                                      
int main()
{
    StrStruct strStruct1{"ab"};
    StrStruct strStruct2{"de"};
    StrStruct strStruct3{"ga"};
                                                                                                                           
    std::vector<StrStruct> strStructList{strStruct1, strStruct2, strStruct3};
    std::vector<const char*>  strListCopy{};
                                                                                                                           
    for (StrStruct strStructEle : strStructList)                                                                           
    {                                                                                                                      
        strListCopy.push_back(strStructEle.myStr);                                                                         
                                                                                                                           
        std::cout << "Memory address for the string got pushed back in is "                                                
                  << &strStructEle.myStr << std::endl;                                                                     
        std::cout << "Memory address for the first element of the string got pushed back in is "                           
                  << (void *) &strStructEle.myStr[0] << "\n" <<std::endl;                                                          
    }                                                                                                                      
    
    std::cout << "Show content of <strListCopy>:" << std::endl;                                                                                                                     
    for (const char*& strEle : strListCopy)                                                                                
    {                                                                                                                      
        std::cout << strEle << std::endl;                                                                                  
    }                                                                                                                                                                                            
}

The following is its output:

Memory address for the string got pushed back in is [address#99]
Memory address for the first element of the string got pushed back in is [address#99]

Memory address for the string got pushed back in is [address#99]
Memory address for the first element of the string got pushed back in is [address#99]

Memory address for the string got pushed back in is [address#99]
Memory address for the first element of the string got pushed back in is [address#99]

Show content of <strListCopy>:
ga
ga
ga

However, if I just simply change the implementation for StrStruct

from:

// This version uses <const char[3]> for <myStr>.
// It does not work as expected. 
struct StrStruct                                                                                                           
{                                                                                                                  
    const char myStr[3];                                                                                                     
};

to

// This version uses <const char*> for <myStr>.
// It works as expected.                                                                                                                      
struct StrStruct                                                                                                           
{                                                                                                                  
    const char* myStr;                                                                                                     
};

Program's output becomes this:

Memory address for the string got pushed back in is [address#10]
Memory address for the first element of the string got pushed back in is [address#1]

Memory address for the string got pushed back in is [address#10]
Memory address for the first element of the string got pushed back in is [address#2]

Memory address for the string got pushed back in is [address#10]
Memory address for the first element of the string got pushed back in is [address#3]

Show content of <strListCopy>:
ab
de
ga

What confuses me is the following:

  1. Why in the first version all the strings have the same value? I tried to use const strStruct& instead of strStruct in the for each loop which solves the problem but I do not understand how.

  2. Why do const char* and const char[] behave so differently? I thought they are largely the same due to the following:

const char myChars[] = "abcde";                                                                                     
const char* myCharsCopy = myChars;                                                                                  
                                                                                                                        
std::cout << myChars << " vs "  << myCharsCopy << std::endl;  

It prints out abcde vs abcde and you can directly assign value of const char[] to const char* without any error.

  1. Why does changing const char[] to const char* solves the problem?

Stack Overflow on running a legacy code C++ Builder 11

A code that was running perfectly on version 4 of the C++ Builder RAD is running into "Stack Overflow on version 11 !? and I am puzzled about how to circumvent the problem. is that possible to increase the stack size while I would be interested in understanding why this happened to begin with, in this new version of the compiler? Regards;

Return pointer to derived class from base class

I would like to now if the following is possible.

I have a templated class called A which inherits from a class called Base. In Base I set a write() function to be rewritten for every derived class.

I am creating a vector to store the references of the Base objects to be printer latter (dataBase).

I would like to know if it is possible to retrieve the reference of the A object whose reference I passed to dataBase.

I have the following code:

#include <iostream>
#include <string>
#include <array>
#include <vector>

class Base
{
    public:
        Base(std::string name):name_(name){}
        virtual ~Base(){}
        virtual void write()=0;

    const std::string& name() const
    {
        return name_;
    }
    
    private:
        std::string name_;
};

template< typename T>
class A : public Base
{
    public:
        A(std::string name):Base(name),name2_(name + "test"){}
        ~A(){}

        void write();

        std::string name2_;

};

template< typename T>
void A<T>::write()
{
    std::cout <<  name2_ << std::endl;
}


int main()
{
        
    A<int> one("one");
    A<double> two("two");
    A<std::array<double,4>> three("three");

    std::vector<Base*> dataBase;
    dataBase.push_back(&one);
    dataBase.push_back(&two);
    dataBase.push_back(&three);

    for(auto i : dataBase)
    {
        i->write();
    }

    A<int>& getOne = lookup("one"); // this is what I want to create
    getOne.name2_  = "worked";

    for(auto i : dataBase)
    {
        i->write();
    }

    return 0;
}

Best Regards

Regarding print a pattern

Question How can I give spaces between numbers? When I add a <<" " after cout<<j the pattern changed. Is there any other way to give spaces between numbers?

code

#include<iostream>
using namespace std;
int main(){
int i,j=1,space,star,n;
cin>>n;
i=1;

Looping

while(i<=n){
space=n-i;
 while(space){
    cout<<" ";
    space--;
 }
star=i;
while(star){
cout<<j<<" ";
j++;
star--;
}
cout<<"\n";
   i++;
}
return 0;

}

output for n=4

    1
   23
  456
 78910

I want this output :-

      1
    2 3
  3 4 5
7 8 9 10

Declare multidimensional Arrays C++ (compared to python)

coming from python I have a hard time understanding the data structure types and their declaration in c++.

To declare and populate a multidimensional array in python you just do as an example:

arr = [[],[]]

for i in range(2):
      arr[i].append(1)

What would be the equivalent in C++? Do I have to use vectors or arrays?

Cheers