dimanche 31 décembre 2023

How to compile an OpenGL project in CMake in Wayland desktop environment?

I'm trying to setup a project that uses OpenGL as library for graphic development; in particular, I want to use CMake for compiling the project to make it cross-platform. I'm running the project on Arch Linux distro with KDE as desktop environment.

This is my CMakeLists.txt:

cmake_minimum_required(VERSION 3.5.0)
project(run VERSION 0.1.0 LANGUAGES C CXX)

include(CTest)
enable_testing()

add_executable(run main.cpp)
target_link_libraries(
    run PUBLIC
    /usr/lib/libglut.so.3
    /usr/lib/libOpenGL.so.0
    /usr/lib/libglfw.so.3.3
    /usr/lib/libGLEW.so.2.2
    /usr/lib/libdecor/plugins-1/libdecor-gtk.so
)
################################################
set(INCLUDE_ROOT_FOLDER "/usr/include")

target_include_directories(
    run PUBLIC
    ${INCLUDE_ROOT_FOLDER}/GL
    ${INCLUDE_ROOT_FOLDER}/GLFW
    ${INCLUDE_ROOT_FOLDER}/libdecor-0
    ${INCLUDE_ROOT_FOLDER}
)
set(CPACK_PROJECT_NAME ${PROJECT_NAME})
set(CPACK_PROJECT_VERSION ${PROJECT_VERSION})
include(CPack)

and this is main.cpp:

#include <iostream>
#include <glew.h>
#include <glut.h>
#include <GLFW/glfw3.h>

int main()
{
    glutInitDisplayMode(GLUT_RGB);
    glfwInit();
    return 0;
}

When compiling, everything is fine. However, this is the error I get at run-time: xkbcommon: ERROR: couldn't find a Compose file for locale "it_IT..UTF-8" (mapped to "it_IT..UTF-8") libdecor-gtk-WARNING: Failed to initialize GTK Failed to load plugin 'libdecor-gtk.so': failed to init

mercredi 27 décembre 2023

Replace boost::timed_wait() with std in c++17

I have a condition variable std::condition_variable my_cond;

I want to be able to replace boost::timed_wait() with an std equivalent one.

If the previously mentioned condition variable was a boost one, then I would use the boost version of timed_wait() like this: cond_.timed_wait(lock,timeout);

where lock is std::scoped_lock lock(mutex_); and timeout is a time that is performed with boost::chrono.

boost:chrono, boost locks and boost mutexes have been replaced with their std analogues. I have yet to find an alternative to timed_wait().

I try to find a function belonging to std, where it receives the lock as the first parameter and an std::chrono type time as a second parameter. Looking at the documentation of the condition_variable::wait here: https://en.cppreference.com/w/cpp/thread/condition_variable/wait

I don't see an overloaded wait function where the second argument is a time type.

Is this conversion from boost::timed_wait() to std::wait() possible?

mardi 19 décembre 2023

Overloaded Templates and non-template functions

I encountered a problem about "Overloaded Templates and non-template functions".

#include <string>
#include <sstream>
#include <iostream>

using namespace std;

// print any type we don't otherwise handle
template <typename T>
string debug_rep(const T &t) {
    ostringstream ret;
    ret << t; // uses T's output operator to print a representation of t
    return ret.str(); // return a copy of the string to which ret is bound
}

// print pointers as their pointer value, followed by the object to which the pointer pointsv
template <typename T>
string debug_rep(T *p) {
    ostringstream ret;
    ret << "pointer: " << p;  // print the pointer's own value
    if (p) {
        ret << " " << debug_rep(*p);  // print the value to which p points
    } else {
        ret << " null pointer";  // or indicate that the p is null
    }
    return ret.str();  // return a copy of the string to which ret is bound
}

string debug_rep(char * p) {
    return debug_rep((string)p);
}

string debug_rep(const char * p) {
    return debug_rep((string)p);
}

int main() {
    string debug_rep(const string& s);
    const char * cp = "hello";
    cout << debug_rep(cp) << endl;

    return 0;
}

string debug_rep(const string& s) {
    return '"' + s + '"';
}

In the book "C++ Primer", they say the cout << debug_rep(cp) << endl; in main function will call debug_rep(const char * p). However, through my test, it actually calls debug_rep(const string& s). So, I wonder why this happened.

samedi 16 décembre 2023

How virtual keyword in virtual inheritance causing a error [duplicate]

I have two set of code :

First case :

#include<iostream>
using namespace std;
class A {
public:
    virtual void display() { cout << "A display \n"; }
};

class B : virtual public A {
public:
    void display() { cout << "B display \n"; }
};

class C : virtual public A {
public:
    void display() { cout << "C display \n"; }
};

class D : public C, public B {
public:
    D() {};
};

int main() {
    D d;
    d.B::display(); // ERROR
}

Error :

Error (active)  E0318   override of virtual function "A::display" is ambiguous
Error   C2250   'D': ambiguous inheritance of 'void A::display(void)'

Second case :

#include<iostream>
using namespace std;
class A {
public:
    void display() { cout << "A display \n"; }
};

class B : virtual public A {
public:
    void display() { cout << "B display \n"; }
};

class C : virtual public A {
public:
    void display() { cout << "C display \n"; }
};

class D : public C, public B {
public:
    D() {};
};

int main() {
    D d;
    d.B::display(); // Output B display
}

The only difference in above two cases is in first one I am making "virtual void display()" in class A, why it is failing in first case while passing in second case?

mercredi 6 décembre 2023

How to Extend C++ Type Traits to Support Pointers and References?

I'm working on a type traits class in C++ and need some assistance in extending its functionality to cover pointers and references. Currently, my class provides traits to check if a type is derived from another, if it's a class or struct, and if it's a primitive or integer type. However, it fails when dealing with pointers or references, as it only considers the direct type.

Here is the existing implementation:

template <typename Derived, typename Base>
using is_derived_from = std::is_base_of<Base, Derived>;

template <typename Type>
using is_class = std::is_class<Type>;

template <typename primitiveT>
using is_primitive = std::integral_constant<bool,
    std::is_floating_point<primitiveT>::value ||
    std::is_integral<primitiveT>::value>;

template <typename TypeInt>
using is_integer = std::integral_constant<bool,
    std::is_integral<TypeInt>::value && !std::is_same<TypeInt, bool>::value>;

template <typename Type, typename Expected>
using is_valid_type = std::integral_constant<bool,
    (is_primitive<Type>::value && std::is_same<Type, Expected>::value) ||
    (is_class<Type>::value && is_derived_from<Type, Expected>::value)
>;

I want to modify is_valid_type to also correctly handle pointers and references. For example, if Type is a pointer or reference to a class derived from Expected, or a pointer/reference to a primitive type that matches Expected, it should still be considered valid.

I've considered using std::remove_pointer and std::remove_reference, but I'm unsure how to integrate them effectively without complicating the code too much.

Any suggestions on how to modify is_valid_type or the approach in general to handle pointers and references efficiently and elegantly in C++?

mardi 5 décembre 2023

std::function - function uses ‘auto’ type specifier without trailing return type in C++ 11 [duplicate]

I'm trying to get a C++14 library working with our C++ 11 code base and having trouble with using std::function (of which I know very little).

Minimal code:

#include <functional>
#include <iostream>

class A
{
public:
    A() {}
    ~A() {}
    
    using CallbackFn = std::function<int(int, double)>;
    auto GetCallbackFn() const { return mCallbackFcn.target<int (*)(int, double)>(); }

private:
   CallbackFn mCallbackFcn;

};

int main()
{
    std::cout << "hi there\n";
}

The code compiles without error with C++14 but with C++11 produces an error:

main.cpp:20:5: error: ‘GetCallbackFn’ function uses ‘auto’ type specifier without trailing return type

I've tried replacing auto with CallbackFn and other permutations but all end up with one error or another.

How do I modify the code to compile under C++11?

Thanks

lundi 4 décembre 2023

How to translate a np.array.view() operation to c++ function

How can I perform this operation in c++ : y = y.view(dtype=int64) * (2**-18), where y is a numpy array where each element holds 16 uint8_t values (128-bits in total).

This is my input y :

[0 0 4 0 0 0 0 0 0 0 0 0 0 0 0 0],
[0 0 4 0 0 0 0 0 0 0 0 0 0 0 0 0],
[209  97 173 255 255 255 255 255 157 210  83   0   0   0   0   0],
[ 99 139 170 255 255 255 255 255   4 214  86   0   0   0   0   0],
[ 46 172 247 255 255 255 255 255 225 125   8   0   0   0   0   0],
[178 109 184 255 255 255 255 255 223 166  72   0   0   0   0   0],
[0 0 4 0 0 0 0 0 0 0 0 0 0 0 0 0],
[0 0 4 0 0 0 0 0 0 0 0 0 0 0 0 0]

and here is the expected output:

y_fpga: [[  1.           0.        ]
 [  1.           0.        ]
 [-20.65447617  20.95567703]
 [-21.36388016  21.70899963]
 [ -2.08185577   2.12292862]
 [-17.89287567  18.16296005]
 [  1.           0.        ]
 [  1.           0.        ]]

What are the rules for uniform initialization of a union [duplicate]

If i compile the following code ...

int main() 
{
    union U
    {
        struct { int i, j; } s;
        long long x, y;
        int z;
    };
    U li { 1 };
}

... either x or y becomes initialized with 1 from what I can deduce from the didsassembly. I noticed that when initializing a LARGE_INTERGER with Win32, where the QuadPart becomes initialized, which is very convenient for me.
But what are the rules for static initalization of unions ? Which part of the union is applied with the initialization value if there's no constructor ?
Edit: I've removed the language-lawyer tag someone applied here because I won't judge on that.

C++11 Memory model: the compiler is restricted to don't introduce new data races

Watching a CppCon talk by Michel Wong on 2015 (called C++1/14/17 atomics and memory model... about minute 33:00), he said two sentences that I didn't understand:

No compiler transformation is allowed to introduce a data race (more restrictions on invented writes and possibly fewer speculative stores and potentially loads)

What kind of "invented writes" and "speculative stores and loads" did compiler do, which of those were "common" before the C++11 memory model but now are forbidden? Were those important optimizations that are now lost? Or they had a tiny impact anyway?

There are atomic memory operations that don't cause races (or they race but are well-defined)

What does he mean here by "there are"? In the hardware or does he is refering to some C++ built-in operations? Which memory operations can "cause races but are well-defined"?

dimanche 3 décembre 2023

Generic Container Template Supporting Various Data Structures in C++ 14

Hi StackOverflow community,

I am working on creating a generic container class template in C++ that can support various data structures like std::vector std::map , etc. My goal is to make this container flexible enough to handle different types of data structures and provide a uniform interface for operations like Add and Remove.

Here is the code snippet that I have so far:

With this implementation I can create a general interface for my container, but I'm specifically looking to improve the functionality of std::map. I want to be able to add and remove items for maps in two ways:

`#include <iostream>
#include <vector>
#include <map>

template <typename T>
class IContainer
{
public:
    virtual void Add(const T& item) = 0;     // Adds item
    virtual void Remove(const T& item) = 0;  // Remove the item if it exists in the container
    virtual ~IContainer() = default;
};

template <typename T, typename ContainerType>
class Container : public IContainer<T>
{
public:
    void Add(const T& item) override
    {
        container.Add(item);
    }

    void Remove(const T& item) override
    {
        container.Remove(item);
    }

private:
    ContainerType container;
};

template <typename T>
class VectorContainer
{
public:
    void Add(const T& item)
    {
        vect.push_back(item);
    }

    void Remove(const T& item)
    {
        // Assuming T has a valid equality comparison
        auto it = std::remove(vect.begin(), vect.end(), item);
        vect.erase(it, vect.end());
    }

private:
    std::vector<T> vect;
};

template <typename Key, typename Value>
class MapContainer
{
public:
    void Add(const std::pair<const Key, Value>& keyValue)
    {
        container.insert(keyValue);
    }

    void Add(const Key& key, const Value& value)
    {
        container[key] = value;
    }

    void Remove(const std::pair<const Key, Value>& keyValue)
    {
        container.erase(keyValue.first);
    }

private:
    std::map<Key, Value> container;
};

int main()
{
    Container<int, VectorContainer<int>> myCont;
    myCont.Add(1); // myCont has a generic interface thanks to IContainer

    Container<std::pair<const std::string, int>, MapContainer<std::string, int>> mapCont;
    mapCont.Add({"key1", 42});
    mapCont.Add("key2", 88); // Using the new Add function (not working)

    return 0;
}
`

Using std::pair as a single parameter. Using separate key and value parameters. I implemented the Add method for both cases, but the container does not support separate keys and key values, so I'm not sure if this is the most efficient or correct way to achieve this flexibility. I'm also looking for suggestions to make this template more compatible with other container types.

Can someone provide insight or improvements on how to do the following:

Efficiently support both append methods for std::map. Generalize this approach to effectively cover other container types. Any advice or code sample would be greatly appreciated!

Thank you!

samedi 2 décembre 2023

Lack of LLVM support

LLVM is such a powerful tool, it is very well established and has a large community. As an undergraduate student I had project and needed to use the LLVM API. Words cannot describe how traumatised I am. I understand that LLVM is huge and very well documented, but I found it extremely hard to do even the most basic tasks. I just wanted to see if others face this problem or is it just me? Are people using LLVM already senior developers with years of experience or do companies such as Apple, Google, etc. gatekeep their resources? I am just very interested in the aspect of low-level compiler design in the future, so any advice would be very much appreciated!

Not only did I spent hours on the official website trying to find my way though, which was like navigating an online labyrinth from the 1990s, I also spent a large amount of time trying to find other web resources/forums, that were mostly useless!

Filter sober in c++ don't pass test

I am working on implementing the Sobel filter for image processing in C++. However, I am encountering unexpected results and failing test cases. I have reviewed the code multiple times, but I cannot pinpoint the source of the issue.

I have provided the relevant parts of my code below. The intensiteH and intensiteV functions are intended to calculate the horizontal and vertical gradients using the Sobel operator, and the intensite function combines these gradients to compute the overall intensity.

#include <stdexcept>
/** @file
 * Filtres de Sobel
 **/
#include <cmath>
#include <vector>
#include <stdexcept>
#include <iostream>
#include <fstream>
using namespace std;

/** Structure de donnee pour representer une image en teintes de gris **/
typedef vector<vector<double> > ImageGris;



/** Infrastructure minimale de test **/
#define CHECK(test) if (!(test)) cerr << "Test failed in file " << __FILE__ << " line " << __LINE__ << ": " #test << endl


/** Une image 4x4 en teintes de gris pour faire des tests **/
ImageGris imgGrisTest = {
    {0, 255, 54.213, 236.589},
    {18.411, 182.376, 200.787, 120},
    {139.583, 172.841, 94.0878, 88.4974},
    {158.278, 172.841, 89.0236, 80.0384}
};



/** Construire une image en teintes de gris depuis un fichier PGM
 * @param source le nom d'un fichier PGM
 * @return une image en teintes de gris
 **/
ImageGris lirePGM(string source) {
   // Déclarations
  ifstream pgm ;    
  pgm.open(source);
  ImageGris imagegris;
       if (!pgm) {
    throw runtime_error("Fichier non trouve: "+source);}
   
 
    if (pgm.is_open()) {
        char type[3]; // stocke type du fichier pbm sous forme de tableau contenant P,2,'\0
        int largeur, hauteur , max ;
       
       // Lecture de l'en-tête du fichier PBM
        pgm >> type >> largeur >> hauteur >> max ;

        if (type[0] == 'P' && type[1] == '2') {
           
          imagegris = vector<vector<double>>(hauteur, vector<double>(largeur)); // car ImageGris est un type                                                                                    et non une variable
           
                                             
                                               
      for (int i=0 ; i<hauteur ; i++){
        for (int j=0 ; j<largeur ; j++){
        pgm>>imagegris[i][j];}        
                                       }
                                     }
   
        pgm.close() ;
                     }
   
      return imagegris ;
                        
}



/** Ecrit une image en teintes de gris dans un fichier PGM
 * @param img une image en teintes de gris
 * @param cible le nom d'un fichier PGM
 **/
void ecrirePGM(ImageGris img, string cible) {
   ofstream pgm ;
  pgm.open(cible);
    if (!pgm) {
    throw runtime_error("Fichier non trouve: "+cible);}
   
    //écriture de l'en-tête
 
     if (pgm.is_open()) {
       pgm<<"P2"<<endl ;  
        pgm<<img[0].size()<<" "<<img.size()<<endl;  
        pgm<<255<<endl;
     
     //" " permet de séparer chaque pixel par un espace  // endl pour aller à la ligne une fois que tous les        pixels sur la ligne ont été écrits
                                                 
      for (int i=0 ; i<img[0].size() ; i++)  {
        for (int j=0 ; j<img.size() ; j++) {
         pgm<<(int)img[i][j]<<" ";         }        
                                             }
        pgm<<endl ;
                         }
        pgm.close();
}








/** Teste si deux images en teintes de gris sont égales modulo imprécision numérique
 * En cas de différence un message est affiché
 * @param a une image en teintes de gris
 * @param b une image en teintes de gris
 * @param precision un flottant positif: la précision souhaitée; typiquement 0.001
 * @return vrai si les images sont égales et faux sinon
 **/
bool ImageGrisEgal(ImageGris a, ImageGris b, float precision) {
    if (a.size() != b.size())  {
        cout << "Nombre de lignes différent" << endl;
        return false;
    }
    for (int i=0; i<a[0].size(); i++)
        if (a[0].size() != b[i].size()) {
            cout << "Nombre de colonnes différent" << endl;
            return false;
        }
    for (int i=0; i<a.size(); i++)
        for (int j=0; j<a[0].size(); j++)
            if (abs(a[i][j] - b[i][j]) > precision) {
                cout << "Valeur differentes en position " << i << "," << j
             << ": " << a[i][j] << " au lieu de " << b[i][j] << endl;
                return false;
            }
    return true;
}

/// BEGIN intensiteH

/** filtre de Sobel horizontal
 * @param img une image en teintes de gris
 * @return une image en teintes de gris de l'intensite horizontale de img
 **/
ImageGris intensiteH(ImageGris img) {
    double gradx ; // gradient horizontal de l'image
    ImageGris intensiteho(img.size(), vector<double>(img[0].size())); //image de retour est de même taille que 
  for ( int i=0; i<img.size();i++){
        for ( int j =0 ; j<img[0].size();j++){
            if (i > 0 && i < img.size() - 1 && j > 0 && j < img[0].size() - 1) {
    gradx = (img[i - 1][j - 1] + 2 * img[i][j - 1] + img[i + 1][j - 1]) - (img[i - 1][j + 1] + 2 * img[i][j + 1] + img[i + 1][j + 1]);
}

        }
   }
 return intensiteho ;
}


/// BEGIN intensiteV

/** filtre de Sobel vertical
 * @param img une image en teintes de gris
 * @return une image en teintes de gris de l'intensite verticale de img
 **/
ImageGris intensiteV(ImageGris img) {
    double grady ; // gradient vertical de l'image
    ImageGris intensitever(img.size(), vector<double>(img[0].size())); //image de retour est de même taille que 
  for ( int i=0; i<img.size();i++){
        for ( int j =0 ; j<img[0].size();j++){
              if (i > 0 && i < img.size() - 1 && j > 0 && j < img[0].size() - 1) {
           grady = img[i-1][j-1] + 2*img[i-1][j] + img[i-1][j+1] - img[i+1][j-1] - 2*img[i+1][j] - img[i+1][j+1] ;
            intensitever[i][j]=grady ;

        }
   }
  }
 return intensitever ;
}


/// BEGIN intensiteHV

/** filtre de Sobel
 * @param img une image en teintes de gris
 * @return une image en teintes de gris de l'intensite de img
 **/
ImageGris intensite(ImageGris img) {
    ImageGris IntensiteHo=intensiteH(img);
    ImageGris IntensiteVe=intensiteV(img);
    ImageGris Intensiteimg(img.size(), vector<double>(img[0].size()));
     for ( int i=0; i<img.size();i++){
        for ( int j =0 ; j<img[0].size();j++){
           double valintensite = sqrt(IntensiteHo[i][j]*IntensiteHo[i][j] +IntensiteVe[i][j]*IntensiteVe[i][j] ) ;
           Intensiteimg[i][j]=valintensite;

        }
    }
    return Intensiteimg ;
}


void testSobel() {
    CHECK( ImageGrisEgal(intensiteH(imgGrisTest),
              ImageGris( {
                  {0, 0, 0, 0},
                  {0, -373.47, 227.507, 0},
                  {0, -22.1312, 323.866, 0},
                  {0, 0, 0, 0}
              }),
              0.001) ); // precision changée
    CHECK( ImageGrisEgal(intensiteV(imgGrisTest),
              ImageGris( {
                  {0, 0, 0, 0},
                  {0, -15.1398, 150.501, 0},
                  {0, -9.0336, 273.023, 0},
                  {0, 0, 0, 0}
              }),
              0.001) );
    CHECK( ImageGrisEgal(intensite(imgGrisTest),
              ImageGris( {
                  {0, 0, 0, 0},
                  {0, 373.777, 272.782, 0},
                  {0, 23.9039, 423.593, 0},
                  {0, 0, 0, 0}
              }),
              0.001) );

    cout << "Vérifier que les images obtenues dans 'sobel/' sont semblables à celles fournies dans 'sobel/correction/'" << endl;
    ecrirePGM(intensite(lirePGM("images/Willis.512.pgm" )), "sobel/Willis.512.pgm");
    ecrirePGM(intensite(lirePGM("images/Baboon.512.pgm" )), "sobel/Baboon.512.pgm");
    ecrirePGM(intensite(lirePGM("images/Billes.256.pgm" )), "sobel/Billes.256.pgm");
    ecrirePGM(intensite(lirePGM("images/Embryos.512.pgm")), "sobel/Embryos.512.pgm");
    ecrirePGM(intensite(lirePGM("images/House.256.pgm"  )), "sobel/House.256.pgm");
}



int main(){

    testSobel();
    return 0 ;
}


I tried to run my code but the tests were failing , here is an example :Valeur differentes en position 1,1: -96.2992 au lieu de -373.47 Test failed in file sobel-tout-en-un.cpp line 200: ImageGrisEgal(intensiteH(imgGrisTest), ImageGris( { {0, 0, 0, 0}, {0, -373.47, 227.507, 0}, {0, -22.1312, 323.866, 0}, {0, 0, 0, 0} }), 0.01) Valeur differentes en position 1,1: 97.482 au lieu de 373.777 Test failed in file sobel-tout-en-un.cpp line 216: ImageGrisEgal(intensite(imgGrisTest), ImageGris( { {0, 0, 0, 0}, {0, 373.777, 272.782, 0}, {0, 23.9039, 423.593, 0}, {0, 0, 0, 0} }), 0.001)

cant understand the logic of the problem specially the last line of the problem need a program written

The following lists the sound level in decibels for several common noises: Noise Decibel Level (dB) Jackhammer 130 Gas lawnmower 106 Alarm clock 70 Quiet room 40 Write a c++ program that reads a sound level in decibels from the user. If the user enters a decibel level that matches one of the noises in the table, then your program should display a message containing only that noise. If the user enters a number of decibels between the noises listed, then your program should display a message indicating which noises the level is between. Ensure that your program also generates reasonable output for a value smaller than the quietest noise in the table and for a value larger than the loudest noise in the table.

cant understand the problem

vendredi 1 décembre 2023

Class with vector of another class doesn't like to change its values

I have a class called intClass that contains a private vector of ints and functions to modify its contents. I have another class called intClassClass that contains a private vector of intClasses and functions to modify and print those. When I attempt to change the innermost ints from the intClassClass, the function runs but the ints don't actually change. I'm pretty sure the solution has something to do with a vector making a copy of the object instead of the object itself, but I'm not sure where that happens or how to fix it.

class intClass
{
private:
    vector<int> ints;
public:
    intClass()
    {
        ints.clear();
    }
    intClass(vector<int> iVec)
    {
        ints = iVec;
    }
    void modifyVec(int newInt, int index)
    {
        cout << "modified vec" << endl;

        ints[index] = newInt;
    }
    void printVec()
    {
        for (int i : ints)
        {
            cout << i << ' ';
        }
        cout << '\n';
    }
    int getInt(int index)
    {
        return ints[index];
    }
};
class intClassClass
{
private:
    vector<intClass> ics;
public:
    intClassClass(vector<intClass> icVec)
    {
        ics = icVec;
    }
    intClass getIC(int index)
    {
        return ics[index];
    }
    void printVec()
    {
        for (intClass i : ics)
        {
            i.printVec();
        }
        cout << '\n';
    }
};

int main()
{
    intClassClass icc = intClassClass({ intClass({ 1,3,4,5,21 }), intClass({2, 4 }) });
    icc.printVec();
    icc.getIC(1).modifyVec(3, 0);
    icc.printVec();
    cout << icc.getIC(1).getInt(0);

    return 0;
}

this outputs this

jeudi 30 novembre 2023

With C++11, how can I generate a warning message in a manner that works in gcc, clang, and MSVC?

When compiling C++11 using clang or gcc, I can generate a warning message at compilation time using:

#warning My message here

This doesn't work on Windows when I use MSVC, though. How can I intentionally generate a warning message that will work regardless of C++ compiler?

This question is not a duplicate of "preprocessor #warning equivalent in Visual C++?" because that question is not attempting to answer the question of how do it in a way that works across compilers.

Template specialisation or function overload

I created a two classes - one can be converted to another by the conversion operator:

struct MyClass{};

struct MyClass2{
    operator MyClass() const { return MyClass{}; }
};

and a specialised template function (specialisation for std::initializer_list<MyClass>):

template<typename T>
void foo(std::initializer_list<T>)
{
}

template<>
void foo(std::initializer_list<MyClass>)
{
    std::cout << "specialised template foo<>()";
}

When I try to call foo with the initializer list mixing MyClass and MyClass2:

foo({MyClass{}, MyClass2{}, MyClass2{}});

compiler opposes (as I am mixing two different types):

<source>:35:8: error: no matching function for call to 'foo(<brace-enclosed initializer list>)'
   35 |     foo({MyClass{}, MyClass2{}, MyClass2{}});
      |     ~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
<source>:19:6: note: candidate: 'template<class T> void foo(std::initializer_list<_Tp>)'
   19 | void foo(std::initializer_list<T>)
      |      ^~~
<source>:19:6: note:   template argument deduction/substitution failed:
<source>:35:8: note:   deduced conflicting types for parameter '_Tp' ('MyClass' and 'MyClass2')
   35 |     foo({MyClass{}, MyClass2{}, MyClass2{}});
      |     ~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

But from some reason if I add an non-template overload of foo for the same type as in template specialisation - it works like a charm!

void foo(std::initializer_list<MyClass>)
{
    std::cout << “overloaded foo()";
}

int main(int argc, char **argv) {
    foo({MyClass{}, MyClass2{}, MyClass2{}}); // Program stdout : overloaded foo()
}

I guess that non-template overload has a priority over templates when compiler looks up for a function. But why it does work with overload and does not work with template specialisation? Is it undefined behaviour? Or is it completely legal to do it so?

Live example: https://godbolt.org/z/5ohhK1jeb

mercredi 29 novembre 2023

how store an image into buffer c++

Hello a camera in my project used to get a pictur and stored it in buffer and then send it to    serverusing c++ language.i have writed this code but the output of buffer  give me this result :

"vØ~Çš_GÙœunô@FUÁs´ò¤Ë°±tF~'µÎF¿>`ðóvC™fÏÃVÔe>kŸlŠÜœ¬4í&΂ž·z>µ£±Ôÿ *ná3ÂJ18 î”!"

but i want the output of the my buffer like this 0x11 ,0x22.....

someone can help please ?

C++ CODE:

#include <iostream>
#include <fstream>
#include <string.h>
#include<vector>
#include <stdio.h>
using namespace std ;
int main() {

 ifstream ifd("C:/Users/GhadaM/Desktop/ghada.jpg",std::ifstream::binary | std::ifstream::in);
 int size = ifd.tellg();
 ifd.seekg(0, ios::beg);
 vector<char> buffer;
 buffer.resize(size); // << resize not reserve
 ifd.read(buffer.data(), size);
 for (char i: buffer)
{ 
  std::cout \<\< i;
}
}

** the ouput:**

Çš_GÙœunô@FUÁs´ò¤Ë°±tF~'µÎF¿>`ðóvC™fÏÃVÔe>kŸlŠÜœ¬4í&΂ž·z>µ£±Ôÿ *ná3ÂJ18 î”!

expected result is:

0x11 ,0x22.....

mardi 28 novembre 2023

Why is a reference to a static variable unresolved in the linker? [duplicate]

Win11
MSVC 2022 (64-bit) - Version 17.8.0
C++14

I have a simple program, below. I can not reference the static variables within a function in the source code (*.cpp file), but I can reference object variables. I get a linker error saying that references to the static variables are unresolved, and the message lists the static variable. If I move the code to the header file then the compilation works.

Another issue (not shown) is I can not reference these static variable from another object. It appears the only reference possible is by using setter and getter functions in the header. Is this part of the C++14 standard?

I don't understand how to reference static variables?

Linker Error: (there is one error for highband and lowband)

Error LNK2001 unresolved external symbol "private: static double Test::highband" (?highband@Test@@0NA) Test D:\home\skidmarks\Projects\Test\Test\Test\Test.obj 1

Code:
// header: Test.h
    class Test  {
       static double  delta;
       static double  highband;
       double lowband;
       void common_setup();
    }; // class Test

 // source: Test.cpp
    # include "Test.h"
    void Test::common_setup() {
       Test::delta = 1.0;
       highband = 1.0;
       lowband = 1.0;
    };

    int main() {}

Why do I get the error "Expression must have class type but it has type Calculator(*)()" when I create an object?

Context:

I am learning C++ and came across the concept of delegating constructors and also member initializer lists. I was creating a very basic calculator class and I came across the error message "Expression must have class type but it has type Calculator(*)()" when creating an object.

The code for my class is

class Calculator 
{

    float num1;
    float num2;

public:
    
    Calculator() : Calculator(0, 0){}
    Calculator(float n1) : Calculator(n1, 0){}
    Calculator(float n1, float n2): num1(n1), num2(n2){}

    //declaring the facilitators
    float add(float n1, float n2);
    float subtract(float n1, float n2);
    float multiply(float n1, float n2);
    float divide(float n1, float n2);

    //destructor
    ~Calculator() {
        std::cout << "Object destroyed" << std::endl;
    }
};

The member functions are not causing any issue so I will leave out their definitions

Within the main function(), when I create my object as

Calculator obj; My program works and I can use the obj to access all the member functions. However, when I write

Calculator obj(); I get the error specified in the title.

I am confused as to why this happens. Shouldn't the default constructor (and then the third constructor through delegation) be invoked in both cases?

Forward Declaration (PIMPL) for External Libraries also used in Method Declarations?

I have looked at a significant number of posts regarding forward declarations/PIMPL, but haven't quite managed to get it to work with the external libraries I'm using. I want to create a shared library where the client does not need to include the external library headers.

This is what I currently have.

################
## myClass.h ##
################

#include <opencv2/opencv.hpp> ------> I want this header in the implementation file instead.

class A;
class B;
class C;

class __declspec(dllexport) myClass
{
public:
    myClass();
    ~myClass();
    cv::Mat myFunction(cv::Mat &img);
private:
    A *_a;
    B *_b;
    C *_c;
};

################
## myClass.cpp ##
################

#include "myClass.h"
#include "a.h"
#include "b.h"
#include "c.h"

myClass::myClass()
{
    _a = new A;
    _b = new B;
    _c = new C;
}

myClass::~myClass()
{
    delete _a;
    delete _b;
    delete _c;
}

cv::Mat myClass::myFunction(cv::Mat &img){ ... }

################
## a.h ##
################

class A
{
public:
    A();
    ... -----> A's methods
};

################
## b.h ##
################

class B{ ... };

################

################
## c.h ##
################

class C{ ... };

################

Here's what I have tried

################
## myClass.h ##
################

namespace cv{
    class Mat; ------> Forward declaration of cv::Mat
}

class A;
class B;
class C;

class __declspec(dllexport) myClass
{
public:
    myClass();
    ~myClass();
    cv::Mat myFunction(cv::Mat &img); ------> Get an error since I'm declaring an incomplete type cv::Mat.
private:
    A *_a;
    B *_b;
    C *_c;
    std::unique_ptr<cv::Mat> _m; ---------> PIMPL for class inside namespace ?
};

################
## myClass.cpp ##
################

#include "myClass.h"
#include "a.h"
#include "b.h"
#include "c.h"
#include <opencv2/opencv.hpp>

myClass::myClass() ------> I'm supposed to do something here ? Inherit _m ?
{
    _a = new A;
    _b = new B;
    _c = new C;
}

myClass::~myClass() -------> Supposed to clear _m (seen = default been used as well) ?
{
    delete _a;
    delete _b;
    delete _c;
}

cv::Mat myClass::myFunction(cv::Mat &img){ ... }

...

Any assistance or guidance would be appreciated. Thanks

dimanche 26 novembre 2023

I have met some errors when I try to complie two cpp files at once in vscode [duplicate]

I am a beginner in learning c++.And here are the details: this is the _test.cpp

#include <iostream>
#include "cat.h"
using namespace std;
int main() {
    speak();
}

and cat.h

#pragma once
void speak();

cat.cpp

#include "cat.h"
#include <iostream>
void speak() {
    std::cout << "meow!!" << std::endl;
}

when I use a powershell to compile them, it's ok.

enter image description here

But when i try to CompileRun the _test.cpp, the errors come. enter image description here

when I CompileRun the cat.cpp, it tells me : enter image description here

And here are my tasks.json and launch.json:

{
    "version": "2.0.0",
    "tasks": [
        /*{
            "type": "shell",
            "label": "compile",
            "command": "g++",
            "args": [
                "-g",
                "${workspaceFolder}\\*.cpp",
                "-o",
                "${fileDirname}\\${fileBasenameNoExtension}.exe"
            ],
            "problemMatcher": [
                "$gcc"  
            ],
            "group": "build"
        },*/
        {
            "type": "cppbuild",
            "label": "C/C++: gcc.exe ",
            "command": "C:\\MinGW\\bin\\gcc.exe",
            "args": [
                "-fdiagnostics-color=always",
                "-g",
                "${fileDirname}\\*.cpp",
                //"${workspaceFolder}\\*.h",
                "-o",
                "${fileDirname}\\${fileBasenameNoExtension}.exe"
            ],
            "options": {
                "cwd": "${fileDirname}"
            },
            "problemMatcher": [
                "$gcc"
            ],
            "group": {
                "kind": "build",
                "isDefault": true
            },
            "detail": "调试器生成的任务。"
        }
    ]
}
{
    "version": "0.2.0",
    "configurations": [
        {
            "name": "C/C++",
            "type": "cppdbg",
            "request": "launch",
            "program": "${fileDirname}/${fileBasenameNoExtension}.exe",
            "args": [],
            "stopAtEntry": false,
            "cwd": "${workspaceFolder}",
            "environment": [],
            "externalConsole": false,
            "MIMode": "gdb",
            "setupCommands": [
                {
                    "description": "Test",
                    "text": "python import sys;sys.path.insert(0, 'C:\\MinGW\\share\\gcc-11.2.0\\python');sys.path.insert(0, 'E:\\mingw64\\share\\gdb\\python');from libstdcxx.v6.printers import register_libstdcxx_printers;register_libstdcxx_printers(None)",
                    "ignoreFailures": true
                },
                {
                    "description": "Enable pretty-printing for gdb",
                    "text": "-enable-pretty-printing",
                    "ignoreFailures": true
                }
            ],            
            "miDebuggerPath": "gdb.exe",
            "preLaunchTask": "compile",
        },
    ]
}

I have searched related questions on youtube and google and have viewed some posts on stackoverflow. So I have modified tasks.json and launch.json. But I can't solve the questions I was wondering if there is a way for me to just run the _test.cpp file and it works!

removing duplicates element in an array

class Solution {
public:
    int removeDuplicates(vector<int>& nums) {
        vector<int>ans;
        int n=nums.size();
       sort(nums.begin(),nums.end());
          for(int i=0;i<n;i++)
    {
        for(int j=i+1;j<n;j++)
        {
            if(nums[i]==nums[j])
            {
                nums[i]=nums[j]=-1;
            }

        }
    }
    for(int i=0;i<n;i++)
    {
        if(nums[i]<0)
        ans.push_back(nums[i]);
    }
    
}`
return nums ; `

};

` i am not getting the ouput,it is showing this

error: expected member name or ';' after declaration specifiers return nums ; ^

samedi 25 novembre 2023

How to make a zero-cost `std::optional`-like class to wrap functions returning value availability

I can call some function which I don't control (external API):

extern bool get_val(int *val) noexcept;

get_val() either sets *val and returns true, or doesn't set *val and returns false.

Is there any way to wrap get_val() such as to return an std::optional-like object instead:

my_optional<int> get_val() noexcept;

while reaching no overhead?

In other words, the two usages below must generate the same/similar instructions:

int v;

if (get_val(&v)) {
    // use `v`
}
if (const auto opt_val = get_val()) {
    // use `*opt_val`
}

vendredi 24 novembre 2023

Handling of error in streambuf::underflow?

I am trying to make sense of the code posted by @dietmar-kühl at:

I do not understand how I am supposed to handle error from within underflow. I have checked the documentation without much luck:

Here is a pseudo code:

class customstreambuf : public std::streambuf
{
    socketstream* stream_;

public:
    explicit customstreambuf(socketstream* stream) : stream_(stream)
    {
    }

    int underflow() override
    {
        if (this->gptr() == this->egptr())
        {
            // fills internal buffer, return num bytes read or -1 on error:
            const int size = this->stream_->fillbuffer();
            if (size < 0)
            {
                throw std::runtime_error("what should I do here?");
            }
            this->setg(this->stream_->buffer_, this->stream_->buffer_, this->stream_->buffer_ + size);
        }
        return this->gptr() == this->egptr()
                   ? std::char_traits<char>::eof()
                   : std::char_traits<char>::to_int_type(*this->gptr());
    }
};

Other posts are relatively evasive for error conditions:

How should I handle error in std::streambuf subclass ? throw an exception (which type) or do something else ?


Just discovered the following awkward post:

which seems kind of mixed java/c++ code (what's IOException ?)


I also found the following:

Which also gives a relative elusive Throwing an exception is indeed the way to go.. Would it make sense to throw something like:

if (size < 0)
{
    throw "socket stream error";
}

could not convert 'str' from 'const QStringBuilder

could not convert 'str' from 'const QStringBuilder<QString,char[5]>' to 'std::string{ask std::basic_string}' code:

template<class T> inline std::string toString(const T&str)
{
  return str;
}

I want know how to resolve it.

jeudi 23 novembre 2023

Nested use of C++ std::async to create threads, which can delay the exception when there is insufficient resources

I am trying to simulate the exception behavior when the number of threads exceeds the linux limit. I found that when I continuously use std::async(std::launch::async, &func) in a thread, without using try catch, the exception is delayed,program seems getting stucked in the function std::async. However, when using try catch, the exception can be caught in time. In the main function, continuous creation until the exception is thrown does not cause any delay. Can you help me explain this behavior?

int asyncTest(uint16_t i)
{
    std::cout<<"@@@asyncTest = "<<i<<" runstart"<<std::endl;
    cpp_sleepMs(1500*i);
    std::cout<<"@@@asyncTest = "<<i<<" runsend"<<std::endl;
    return i;
}

//running in a thread,when using try catch,it will directly throw exception.
    std::shared_future<int> periodFutTestArray[2000];
//  try {
        for(uint16_t i_cyc=0;i_cyc<2000;i_cyc++)
        {
            std::cout << "@@@asyncTestCreate = "<<i_cyc <<"start"<<std::endl;
            periodFutTestArray[i_cyc] = std::async(std::launch::async, &asyncTest,i_cyc);
            cpp_sleepMs(100);
            std::cout << "@@@asyncTestCreate = "<<i_cyc <<"end"<<std::endl;
        }
//  }catch (const std::exception& e) {
//     std::cerr << "Caught exception: " << e.what() << std::endl;
//  }

std::async stuckedprogram endusing try catchrunning in main func

How can I inherit a magic static singleton?

I would like to inherit from a magic static singleton in a derived:

#include <iostream>

int main();

class SingletonBase{
protected:
    int i=0;
    SingletonBase(int){}
    //
    friend int main();
    static void show(){
        static SingletonBase s(2); // this is sometimes referred to as the "magic static singleton pattern"
        s.i++;
        std::cout << "SingletonBase::i="<<s.i<<"\n";
    }
};

class Singleton: public SingletonBase{
private:
    Singleton(int):SingletonBase(int{}){}
    int j=0; // unfortunately, Singleton has data, too.
public:
    static void show(){
        static Singleton s(3);
        s.i++;
        s.j++;
        std::cout << "Singleton::SingletonBase::i="<<s.i<<". Singleton::j="<<s.j<<"\n";
    }
    //
};

int main() {
    Singleton::show();
    Singleton::show();
    Singleton::show();
    Singleton::show();
    SingletonBase::show();
    SingletonBase::show();
    SingletonBase::show();
    Singleton::show();
    Singleton::show();
    Singleton::show();
    Singleton::show();
}

The output is:

Singleton::SingletonBase::i=1. Singleton::j=1
Singleton::SingletonBase::i=2. Singleton::j=2
Singleton::SingletonBase::i=3. Singleton::j=3
Singleton::SingletonBase::i=4. Singleton::j=4
SingletonBase::i=1
SingletonBase::i=2
SingletonBase::i=3
Singleton::SingletonBase::i=5. Singleton::j=5
Singleton::SingletonBase::i=6. Singleton::j=6
Singleton::SingletonBase::i=7. Singleton::j=7
Singleton::SingletonBase::i=8. Singleton::j=8

But what I expected (and need) is for i to increase by 1 in each output line. That is, the Singleton (there is supposed to be only one) shall inherit the SingletonBase.

How can this be done?

Remark

I cannot unfriend main.

The application context is that I have two distinct types template<typename T>ElementA and template<typename T>ElementB with much mutual functionality. So I inherit both from a template<typename T>ElementBase. Both are putting stuff on a StackA<T> and StackB<T>, respectively, that share a lot functionality in turn. So I inherit both stacks from StackBase<T>. In the above example, main is the ElementBase calling upon SingletonBase; and SingletonBase in turn is StackBase, since being the base of Singleton, which models StackA / StackB.

Unfriending main means ElementBase<T> cannot push into StackBase<T>, meaning I'd have to implement everything for A and B redundantly.

mercredi 22 novembre 2023

Live suggestions in a dictionary c++

I am doing a course project where I have to build a dictionary. I have already made the dictionary using the trie. The problem now is that I have to show live suggestions as the user types the word just like on google. I cant it do the normal way like first typing the word and pressing enter. Also the delete function is not working. This is my current code so far. (I am on windows and using visual studio)

    `#include<iostream>
    #include<list>
    #include<vector>
    using namespace std;

    struct node {
    node* next[26];
    bool end;
    node()
    {
        for (int i = 0; i < 26; i++)
        {
            next[i] = nullptr;
        }
        end = false;
    }
   };

    class Trie
    {
      private:
    node* root;
    void getSuggestions(node* curr, string str, list<string>& res, string curnt)
    {
        if (curr == nullptr) { return; }
        if (curr->end == true)
        {
            res.push_back(curnt);
        }
        for (int i = 0; i < 26; i++)
        {
            if (curr->next[i])
            {
                getSuggestions(curr->next[i], str, res, curnt + char('a' + i));
            }
        }
    }
    bool removeHelper(node* curr, string str, int level, int len)
    {
        if (curr == nullptr) { return false; }

        // Base case: If we have reached the end of the word
        if (level == len)
        {
            if (!curr->end)
            {
                return false; // Word not present
            }

            curr->end = false; // Unset the end flag to indicate removal

            // If the current node has no children, it can be deleted
            if (!hasChildren(curr))
            {
                delete curr; // Delete the node
                return true;  // Node can be deleted
            }

            
        }

        // Recursive case: Continue to the next level
        int index = str[level] - 'a';
        if (removeHelper(curr->next[index], str, level + 1, len))
        {
            // If the child node is marked for deletion, delete it
            delete curr->next[index];
            curr->next[index] = nullptr;

            // Check if the current node can also be deleted
            if (!hasChildren(curr) && !curr->end)
            {
                delete curr;          // Delete the node
                return true;          // Node can be deleted
            }
        }

        return false;
    }

    // Check if a node has any children
    bool hasChildren(node* curr)
    {
        for (int i = 0; i < 26; i++)
        {
            if (curr->next[i])
            {
                return true;
            }
        }
        return false;
    }
      public:
    Trie()
    {
        root = new node();
    }
    void insert(string str)
    {
        node* curr = root;
        for (char c : str)
        {
            if (!curr->next[c - 'a'])
            {
                curr->next[c - 'a'] = new node();
            }
            //cout << curr->next[c - 'a']<<" ";
            curr = curr->next[c - 'a'];
        }
            curr->end = true;
    }
    void remove(string str)
    {
        if (str.empty())
        {
            cout << "Invalid input for removal";
            return;
        }

        if (removeHelper(root, str, 0, str.length()))
        {
            cout << "Word removed successfully";
        }
        else
        {
            cout << "Word not found";
        }
    }
    void suggest(string str)
    {
        node* curr = root;
        for (char c : str)
        {
            if (!curr->next[c - 'a'])
            {
                cout << "Word not found";
                return;
            }
            curr = curr->next[c - 'a'];
        }
        list<string> res;
        //vector<string> res;
        getSuggestions(curr, str, res, "");
        cout << "-------\n";
        int i = 0;
        for (auto c : res)
        {
            cout << str << c << "\n";
            i++;
            if (i == 10) { return; }
        }
    }
    void find(string str)
    {
        node* curr = root;
        for (char c : str)
        {
            if (!curr->next[c - 'a'])
            {
                cout << "Word not found";
                return;
            }
            curr = curr->next[c - 'a'];
        }
        list<string> res;
        //vector<string> res;
        getSuggestions(curr, str, res, "");
        cout << "-------\n";
        int i = 0;
        for (auto c : res)
        {
            cout << str << c << "\n";
            i++;
            if (i == 1) { return; }
        }
    }
    };

    int main()
    { 
    string str;
    Trie T;
    int choice = 0;
    while(true)
    {
        cout << "\n1.Insert";
        cout << "\n2.find";
        cout << "\n3.suggest";
        cout << "\n4.exit";
        cout << "\n5.del";
        cout << "\nEnter you choice: ";
        cin >> choice;
        if(choice==1)
        {
            int n;
            cout << "\nEnter total number of words to insert: ";
            cin >> n;
            for (int i = 0; i < n; i++)
            {
                cout << "Insert new word\n";
                cin >> str;
                T.insert(str);
            }
        }
        if(choice==2)
         {
            string st;
            cin >> st;
            T.find(st);
        }
        if (choice == 3)
        {
            string st;
            cin >> st;
            T.suggest(st);
        }
        if (choice == 4)
        {
            break;
        }
        if (choice == 5)
        {
            string st;
            cout << "Enter word to remove \n";
            cin >> st;
            T.remove(st);
        }
    }
    return 0;
   }`

How to prevent copy elision when implementing custom array functionality? [closed]

I'm writing a class CValue in C++, which is supposed to be an analog of values in JavaScript. CValue object can be almost every type, depending on initialization/assignment: primitive value (bool, int, double, string objects, etc.), array, or even an object (a hash map with property names as keys and CValue as values). All work just fine, but I have some troubles with arrays and object element access. I will explain the problem for arrays.

To access elements of an array, CValue has the following method:

CValue CValue::operator[](int index)

Notice, that I return CValue, not CValue& - that is because the object on which this operator was called may not be an array. In that case I just return empty CValue, which is like undefined from JS. When I call operator[] on a valid array value and given index is correct, then I return a reference-like CValue object, which contains a pointer to actually stored element in the array under the hood. This value is not a copy of original array element, because I want to be able to change it like so:

arr[0] = 42;

If I were returning a copy of array element, then, obviously, I would change its copy, not the original element.

So I only need to return reference-like CValue objects when I access elements of arrays (or objects). In other scenarios I just make a copy of another value. For example:

CValue var1 = 42;
CValue var2 = var1;  // var1 = 42, var2 = 42
var2 = 100;          // var1 = 42, var2 = 100

And now, finally, I can describe the problem to you. When I write

CValue var = arr[0];

compiler thinks, that it is a great opportunity for him to use copy elision, and instead of using copy constructor (which will make a copy of value) it just replaces newly created value with reference-like CValue object, returned from operator[]. This leads to following unwanted behaviour:

arr[0] = 42;
CValue var = arr[0];  // var = 42,  arr[0] = 42
var = 100;            // var = 100, arr[0] = 100

I can use variable var to fully access first element of arr. But I just wanted to make a copy of it. So my question is:

How can I prevent copy elision here to avoid this unwanted begaviour?

NOTE: I know I can disable it completely in compiler flags, but I don't want to do this, because copy elision is quite useful overall.

Is there any potential problem when casting an int to enum when the int is greater than the number of possible values?

Is there any potential problem that I should be aware of when casting an int to enum when the int is greater than the number of possible values, say

Here is the code snippet, which seems work well:) :

#include <iostream>
 
 int main()
 {
     enum Demo{NONE=0, OK, HEART, OTHERS, FULL}; 
     enum Demo demo = static_cast<enum Demo>(9);

     std::cout << static_cast<int>(demo) << std::endl;
     std::cout << (static_cast<int>(demo) == 9) << std::endl;
 }

mardi 21 novembre 2023

How to make initializer lists robust to code changes?

There is this code:

#include <iostream>

struct Range {
    //bool enabled = false;
    //int index = 0;
    int begin = 0;
    int end = 0;
};

int main()
{
    Range r = { 2, 3 };
    std::cout << r.begin << " " << r.end;
}

If I change the contents of the Range structure by uncommenting one of the commented lines, the program compiles, but does not work correctly. If I add a bool type field to the beginning of Range, the compiler at least issues a warning. But if I add a field of type int to the beginning of Range, then there is not even be any warnings.

Is there any way to make sure that when the contents of a structure changes, all initializer lists that initialize it become invalid or at least issue a warning during compilation? Or maybe is there some other reliable way to find all initializer lists of this structure in the code?

In general, I need some reliable way to find all initializers and make sure that the structure is correctly initialized after changes.

How can an object find that is rvalue reference(unnamed value) in C++? [duplicate]

I have a class named Matrix. I want overload operator ! that return transpose of matrix. When the main matrix is a unnamed object I prefer to use it's allocated memory to construct transpose matrix, otherwise use new matrix. How can I do this.(We assume that the number of rows and columns of the matrix is ​​equal)

class Matrix {
// ...
/* transpose of a unnamed matrix */
Matrix&& operator !() 
{
    for (int i = 0; i < rows_; ++i)
        for (int j = 0; j < cols_; ++j)
            std::swap(data[i][j],data[j][i]);
    return std::move(*this);
}

/* transpose of a matrix that is not rvalue refrence */
Matrix operator !()const
{
        Matrix ret(cols_, rows_);
    
        for (int i = 0; i < rows_; ++i)
            for (int j = 0; j < cols_; ++j)
                ret.data[j][i] = data[i][j];
        return temp;
}
};

The compiler does not allow me to have both overload together.

template specialization of unique_ptr generating member function

I am trying to make comm class with template variable. My colleague ask me to use std::unique_ptr for memory management. But I think I failed to implement polymorphysm.

I wrote code as the following.

template<typename env>
class Comm{
public:
    Comm(size_t rank, size_t world_size): rank(rank), world_size(world_size) {};
    Comm(){};
    ~Comm(){};
    int rank;
    int world_size;
}
template<typename env>
std::unique_ptr<Comm<env> > createComm(int argc, char *argv[]){
    std::cout << "empty comm" << std::endl;
    return std::make_unique< Comm<env> >();
};
template<>
std::unique_ptr<Comm<MKL> > createComm(int argc, char *argv[]){
    std::cout << "SERIALcomm" << std::endl;
    return std::make_unique< Comm<MKL> >( 0, 1 );
}
template<>
std::unique_ptr<Comm<MPI> > createComm(int argc, char *argv[]){
    std::cout << "MPIcomm" << std::endl;
    MPI_Init(&argc, &argv);
    int myRank ,nRanks;
    MPI_Comm_rank(mpi_comm, &myRank);
    MPI_Comm_size(mpi_comm, &nRanks);
    assert(nRanks>0);
    assert(myRank>=0);
    return std::make_unique< Comm<MPI> >( (size_t) myRank, (size_t) nRanks );
}

And here is a test code

int main(int argc, char* argv[]){
    auto comm = createComm<MKL>(argc, argv);
    return 0;
}

and I've got "empty comm" as a output.

What should I do to make MKL type or MPI comm object using createComm method?

lundi 20 novembre 2023

Passing processor-function in library for ESP AsyncWebServerRequest

I'm trying to include the ESPAsyncWebServer lib in an own C++ class/library. I'm struggling to pass the processor function when starting a server.

Same problem was discussed here: Calling member function by pointer Passing a function as a parameter within a class ...but I can't find the solution.

My code looks like this:

code.ino:

#include "SoftwareUpdater.h"

AsyncWebServer server(80);
SoftwareUpdater Updater(&server);

void setup() {
  Serial.begin(115200);
  Updater.initialise();
}

void loop() {
}

Softwareupdater.cpp:

#include "SoftwareUpdater.h"

SoftwareUpdater::SoftwareUpdater(AsyncWebServer *_server) {
  server = _server;
}

void SoftwareUpdater::initialise() {
  server->on("/manager", HTTP_GET, [](AsyncWebServerRequest *request) {
    request->send(SPIFFS, "/index.htm", String(), false, [&](const String &var) -> String {
      return processor(var);
    });
  });
  server->begin();
};

String SoftwareUpdater::processor(const String &var) {
  if (var == "var_manager") {
    return "text";
  }
};

Softwareupdater.h:

#ifndef SoftwareUpdater_h
#define SoftwareUpdater_h

#include "FS.h"
#include "SPIFFS.h"
#include <ESPAsyncWebServer.h>

class SoftwareUpdater {
private:
  void _setupAsyncServer();

public:
  AsyncWebServer *server;
  String processor(const String &var);

  SoftwareUpdater(AsyncWebServer *server);
  void initialise();
};

#endif

This is the error I get

samedi 18 novembre 2023

RunTime Error - member access within null pointer of type 'ListNode'

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode() : val(0), next(nullptr) {}
 *     ListNode(int x) : val(x), next(nullptr) {}
 *     ListNode(int x, ListNode *next) : val(x), next(next) {}
 * };
 */
class Solution {
    int getLength(ListNode* head){
        int length = 0;
        ListNode* temp = head;
        while(temp != NULL){
            length++;
            temp = temp -> next;
        }

        return length;
    }
public:
    ListNode* removeNthFromEnd(ListNode* head, int n) {
        int pos = getLength(head) - n , cnt = 1;
        ListNode* temp = head;
        while(cnt != pos){
            temp = temp -> next;
            cnt++;
        }

        ListNode* nodeToDelete = temp -> next;
        temp -> next = temp -> next -> next;
        delete(nodeToDelete);

        return head;     

    }
};

Hey there I'm trying to solve this simple problem of removing the nth node from the end. But after running I'm facing a runtime error:

Line 27: Char 28: runtime error: member access within null pointer of type 'ListNode' (solution.cpp) SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior prog_joined.cpp:36:28

The implementation of add_rvalue_reference

Why does the result become an rvalue reference when deducing from a function returning type directly for a function type, while the implementation in bool_constant yields the correct type?

#include <type_traits>

using namespace std;

template <typename T>
T &&test_rvalue_reference(int);
template <typename T>
T test_rvalue_reference(...);

static_assert(is_same_v<decltype(test_rvalue_reference<void ()>(0)), add_rvalue_reference_t<void ()>>);     // error
static_assert(is_same_v<decltype(test_rvalue_reference<void ()>(0)), void (&)()>);      // OK, lvalue reference


template <typename, typename T>
struct select_second_type {
    using type = T;
};
template <typename T>
typename select_second_type<T &&, true_type>::type try_add_rvalue_reference(int);
template <typename T>
false_type try_add_rvalue_reference(...);

template <typename T, bool = decltype(try_add_rvalue_reference<T>(0))::value>
struct add_right_value_reference {
    using type = T &&;
};
template <typename T>
struct add_right_value_reference<T, false> {
    using type = T;
};

static_assert(is_same_v<typename add_right_value_reference<void ()>::type, add_rvalue_reference_t<void ()>>);       // OK
static_assert(is_same_v<typename add_right_value_reference<void ()>::type, void (&&)()>);       // OK, rvlaue reference

vendredi 17 novembre 2023

How to Improve XORing of large uint64 arrays?

I want to xor large shifted arrays, following is portable version of that function for easy of explanation. How I can improve this computation? I have tried using AVX2 but didnt see much improvement. Currently for the DB showing in the example below it takes 50ms to process everything, which is 12 GB/s, I will appreciate any tips to improve the computation.

#include <iostream>

uint64_t partition_size = 4096;
uint64_t entry_size = 256; // bits
uint64_t DB_size = 16777216;
uint64_t *DB = new uint64_t[DB_size * entry_size/64];
uint64_t *result = new uint64_t[partition_size];

//partition_index will be a random multiple of partition_size, e.g. 0, 8192, 4096 etc
//random_offset will be a random number in [0, partition_size]
void xor_shifted_arrays(uint32_t partition_index, uint32_t random_offset)
{
    auto uint64_per_entry = entry_size / sizeof(uint64_t);

    int shift_offset;
    uint32_t shift;
    
    for (int i = 0; i < partition_size  ; i = i + 1)
    {
        shift = (i + random_offset) & (partition_size - 1);
        shift_offset = shift * uint64_per_entry;
        
        for (int j = 0; j < uint64_per_entry; j=j+4){
            result[shift_offset + j] = result[shift_offset + j] ^ DB[partition_index + j];  
        }
        partition_index = partition_index + uint64_per_entry;
    }
}

How to iterate over ranges of a std::vector

I have a question on what's the best way to iterate over slices/ranges of a vector with C++11 or C++14. Let's say we have a std::vector that holds a bunch of values:

std::vector<int> v = {0,1,2,3,4,5,6,7,8,9,10};

This vector is used as input to calculate a value from n contiguous values, in operations similar to a moving average. For this purpose, I have a function foo that takes n contiguous elements as input, does some math, and outputs a value. This means this function looks something like the following declaration:

int foo(const std::vector<int> &v_range);

I want to apply foo to all elements of v to map them to another vector. I could pull that off by iterating over the vector, extract a subvector, and pass it to foo. See code below.

// Example program
#include <vector>
#include <iostream>

int foo(const std::vector<int> &v) {
    
    std::cout << "[";
    for(int e: v) {
        std::cout << e << ",";
    }
    std::cout << "]" << std::endl;
    return 0;
}

int main()
{
  std::vector<int> v = {0,1,2,3,4,5,6,7,8,9,10};
  std::vector<int> v_out;
  std::vector<int> v = {0,1,2,3,4,5,6,7,8,9,10};
  std::vector<int> v_out;
  const int n = 3;

  for (auto begin = v.begin(), end = std::next(v.begin(), n);
       std::next(begin, n - 1) != v.end();
       ++begin, ++end) {
      std::vector<int> v_slice(begin, end);
      v_out.push_back(foo(v_slice));
  }
}

Demo

The above works, but not only does it require a lot of boilerplate code but it also needlessly copy elements around.

I was wondering if C++ provided any clever way to easily iterate over slices/ranges of elements of a vector, which could be passed to either std::transform or std::for_each.

Alternatively, I was wondering if C++ offered any way to transform the input vector as a vector of vector ranges, similar to the following pseudocode:

  std::vector<int> v = {0,1,2,3,4,5,6,7,8,9,10};


  std::vector<std::vector<int>> v_sliced = { 
    {0,1,2},
    {1,2,3},
    {2,3,4}
    ///...
    {8,9,10}
  };

Any input is welcomed.

Occasional double free error from vector::push_back(std::string) in a single threaded context [closed]

I'm quite puzzled by this one. I have a push_back to a vector that consistently (but only once every few hours) produces a double free crash. This code is only called in a single-threaded context. The docs seem to state that these operations should be safe.

bool ready_to_sell = true;
orders = std::vector<std::string>();

void submit_order(std::string order_id){
    // Why is this causing a free issue?
    orders.push_back(order_id);
    if(ready_to_sell){
        ready_to_sell = false;
        rdx.publish("SELL",asks.back()); // Redis client
        orders = std::vector<std::string>();
    } else {
        std::cout << "ALREADY SELLING\n";
    }
}

Here is part of the leaks/valgrind output showing this is the problem spot - line 7 shows it is the push_back causing the problem.

8   seller                        0x100b8c03c submit_order(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >) + 44  
7   seller                        0x100b8a9b8 std::__1::vector<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::allocator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > >::push_back(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&) + 72  vector:1661
6   venue_stat_arb                        0x100de70bc void std::__1::vector<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::allocator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > >::__construct_one_at_end<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&>(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&) + 88  vector:948

jeudi 16 novembre 2023

Why does std::mutex make things wrong here?

I edit code in VS (not vs code), and run it in WSL 2.


#include <iostream>
#include <deque>
#include <vector>
#include <list>
#include <mutex>
#include <condition_variable>
#include <string.h>


const int a = 10000;
const int b = 20000;

class myclass
{
public:
    myclass(int sz1, int sz2) :s1(sz1, '\0'), s2(sz2, '\0')
    {
        std::cout << "constructor\n";
    }
private:
    std::string s1, s2;
    std::mutex m1, m2;
};

int main()
{
    std::vector<myclass> m;
    for (int i = 0; i < 10000; i++)
    {
        m.emplace_back(a, b);
    }
    std::cout << m.size();
    return 0;
}

For code above, there are some errors when build.

But if I comment out std::mutex m1, m2;, it works well. So it seems like it is caused by mutex. Why?

Thank you for your help.

Code runs slower on Intel XEON than Intel i7?

I have some code in which the following function is responsible for 95% of computation

void processServerData(uint32_t partIndex, uint32_t dataOffset, uint64_t *outputData, uint32_t dataSize, uint32_t partSize) {
    auto bytesInEntry = dataSize / sizeof(uint64_t);

    __m256i a, b, r;
    int outputIndex, dataIndex;
    uint32_t rotationOffset;

    int k = 0;
    for (int i = 0; i < partSize; i = i + 1)
    {
        k = i;
        rotationOffset = (k + dataOffset) & (partSize - 1);

        outputIndex = rotationOffset * bytesInEntry;
        dataIndex = partIndex + k * bytesInEntry;

        a = _mm256_loadu_si256((__m256i *)(outputData + outputIndex));
        b = _mm256_loadu_si256((__m256i *)(DB + dataIndex));
        r = _mm256_xor_si256(a, b);
        _mm256_storeu_si256((__m256i *)(outputData + outputIndex), r);
    } }

Here outputData is pointing to exactly same array for each function call. As you can see at high level the code is just XOR two arrays at some offset and storing result into outputData.

I am using following flags

-mavx2 -march=native -O3 

Now here is the question

I ran this code on two instances.

  • Intel(R) Core(TM) i7-7700K CPU @ 4.20GHz running MacOS 13.6, 16 GB DDR4 RAM, compiler Apple clang version 15.0.0 (clang-1500.0.40.1)
  • AWS r7i.2xlarge Intel(R) Xeon(R) Platinum 8488C with Ubuntu, 64 GB DDR5 RAM, compiler g++ (Ubuntu 11.4.0-1ubuntu1~22.04) 11.4.0

I have observed following behavior

  • For smaller database of 32 MB AWS is at least 2x faster than MAC
  • Although for larger database of 8 GB MAC is 2x faster than AWS
  • For AWS I tried doing avx512 and the code got 2x more slower

I assume that this is because Mac has faster processor?

But as this is memory heavy code, AWS's large cache is not helpful?

Is there any optimization that I could do that will help with AWS?

I am very new to such optimizations for any guidance will be highly appriciated

mercredi 15 novembre 2023

C++ Phase 1 Translation Set of Source File Characters: Before vs. Post C++11, before C++23

cppreference's page on phases of translation , for Phase 1 of translation (prior to C++23), has a note in its Step 2. that:

The set of source file characters accepted is implementation-defined (since C++11)

This is also echoed in a working draft of the spec (for instance, for C++20).

Given that, before C++23, it's always appeared to be implementation-defined for how bytes of the source code file get mapped to characters of the basic source character set, what has the above rule added as of C++11 achieving? Ie what's the net change for having it vs. not? This may just be a reading comprehension question, but it seems unclear to me, as then it goes on to say:

Any source file character that cannot be mapped to a character in the basic source character set is replaced by its universal character name (escaped with \u or \U) or by some implementation-defined form that is handled equivalently.

For instance, does that C++11 addition mean that it's up to the implementation to determine which characters to even consider mapping to the basic source character set or to a universal character name at all (ie that it's allowed to skip characters in the source file and not translate them at all)? Otherwise, by the just-above point about either being mapped to a basic source character or a universal character name or equivalent, it's not clear to me what this C++11 rule is achieving beyond step 1 of phase 1 on that cppreference page, namely that:

The individual bytes of the source code file are mapped (in an implementation-defined manner) to the characters of the basic source character set

mardi 14 novembre 2023

Sqlite_orm "and" operator operands doesn't match

I'm building a database repository class with every method the user needs to interact with a sqlite_orm database. In the method that checks if the user exists based on an username and password provided and I can't get pass this error from the "and" operator :

Severity Code Description Project File Line Suppression State Error C2678 binary '&&': no operator found which takes a left-hand operand of type 'sqlite_orm::internal::where_t<sqlite_orm::internal::is_equal_t<std::string UserDB::* ,std::string>>' (or there is no acceptable conversion)

This is the method :

int8_t DatabaseRepository::CheckUserExists(const std::string& inputUsername, const std::string& inputPassword)
{
    auto result = m_db->select(sql::columns(&UserDB::id),
        sql::where(sql::c(&UserDB::username) == inputUsername) and sql::c(&UserDB::password) == inputPassword);

    if (!result.empty())
        return result.front();
    else
        return -1;
}

I've checked the sqlite_orm pdf documentation and I've wrote the method as it is in the pdf and even Chat gpt can't solve this too.

Internal state of std::discrete_distribution and random numbers quality

I am iteratively generating random numbers via std::discrete_distribution. Does the quality of random numbers degrade if after each iteration I reset the internal state of the distribution (which is equivalent to creating std::discrete_distribution object inside the loop):

// inputs:
//   int n_samples
//   int n_energies
//   double energies[n_energies]

std::mt19937_64 generator;

for (int i = 0; i < n_samples; ++i ) {
    std::discrete_distribution<int> d(energies, energies + n_energies);

    int index = d(generator);

    // DO SMTH WITH INDEX
    // energies array may change between iterations here.
}

The reason I am asking is that energies may change between iterations (depending on the algorithm flow, which is not predictable).

In one border case, they change every iteration so above code is ok, since there is nothing I can do here.

In the other border case, they do not change between iterations at all. Which is equivalent to resetting internal state of std::discrete_distribution while probabilities are the same.

In the latter case, is the quality of generated random numbers inferior to the quality when distribution state is not reset (i.e., std::discrete_distribution object is created outside the loop)?

samedi 11 novembre 2023

Moving third party library from header file

I have the following code snippet:

#include <nats/nats.h>

class MyClass
{
public:
    // some functions here
private:
template<typename T, void (*DestroyFn)(T*)>
decltype(DestroyFn) makeDeleter()
{
    return [](T* ptr)
    {
        DestroyFn(ptr);
    };
}

std::unique_ptr<natsOptions, std::function<void(natsOptions*)>> m_options{
    nullptr,
    makeDeleter<natsOptions, natsOptions_Destroy>()};
std::unique_ptr<natsConnection, std::function<void(natsConnection*)>> m_connection{
    nullptr,
    makeDeleter<natsConnection, natsConnection_Destroy>()};
std::unique_ptr<natsSubscription, std::function<void(natsSubscription*)>> m_subscription{
    nullptr,
    makeDeleter<natsSubscription, natsSubscription_Destroy>()};
};

If I wouldn't have required custom deleters I could easily forward declare used types from NATS library. But is it possible to do same if I have makeDeleter function template deleter which calls actual functions from the library (e.g., natsOptions_Destroy)? The thing is that the reviewers of the code require to not include 3rd party library in the current header file, but on the other hand I don't see the issue in my case, because current header is included only in two .cpp file, hence only two translation units will be recompiled if something changes in the nats.h.

vendredi 10 novembre 2023

Cstring errors in C++ [closed]

I cant seem to figure this out, I'm supposed to take an argument as a cstring and keep getting the error:

string.h:18:18: error: expected ‘)’ before ‘input’
      String (cstring input) {
                       ^
     make: *** [string.o] Error 1

This is the rest of the segment of code:

 String (cstring input) {
   int i = 0;
   while (input[i] != "\0") size++;
   buffer = get_new_buffer(size+1);
  }

I tried to create it using a string, but was told im not allowed to, havent been able to figure out anything else.

jeudi 9 novembre 2023

Don't understand somethings in C++

class Rotations
{
public:
        static bool containAllRots(const std::string &strng, std::vector<std::string> &arr)
        {

            if (strng == "")
                return true;

            std::string value = strng;

            for (size_t i = 0; i < strng.length(); i++)
            {
                std::rotate(value.begin(), value.begin() + 1, value.end());

                if (std::find(arr.begin(), arr.end(), value) == arr.end())
                    return false;
            }

                 return true;
        }
};

1- Why was another variable declared as value instead of using a string directly? Why does an error occur when I use a string directly?

2- What exactly does this line in the code mean? std::find(arr.begin(), arr.end(), value) == arr.end()

Two Dimensional Array init in C++11

I'm trying to get full understandig of C++ arrays init.

Here is the code snippet:

int main() {
    const int n= 20;
    int m;
    m = n+10;
    int (*a)[m] = new int [n][m]; //1
    int *w = new int [m]; //2
    int (*b)[n] = new int [m][n]; //3
    int (*d)[n] = new int [n][n]; //4
}

If i'll try to comple this code, i'll get the errors:

error: array size in new-expression must be constant
error: the value of 'm' is not usable in a constant expression
note: 'int m' is not const

I have read, that for array init variable must to be a const, but, if so, then i have some questions:

  1. Why is it possible to init single-dimensional array (2) using non-const variable m?
  2. Why is it possible to init two-dimensional array (3) using non-const variable m at rows number position?
  3. Why isn't possible to init two-dimensional array (1) using non-const variable m at column number position?

Just in case, I'll clarify, that i'm not looking for workarounds, another ways, etc. Just for theoretical knowledge.

Thank you!

mercredi 8 novembre 2023

C++ Vector Declaration Syntax

Confused why vector declaration syntax is different than any other data structure. For example an Array.

vector<int> myvector

Whereas an array can be declared as such

int arr[] = {1, 2}

C++ "atomic_compare_exchange_strong" apply to non-atomic variable

std::shared_ptr<int> node;
int *expect = new int(1);
int *desire = new int(2);
atomic_compare_exchange_strong(&node, &expect, desire)

What makes this code run as I image? the "node" is not modified by atomic What conditions does "node" need to meet? I think volatile modification is needed in C, but I don’t know what is needed in C++.

I want to ask the apply conditions of atomic_compare_exchange_strong

mardi 7 novembre 2023

Calling the std::future destructor when an exception is thrown

There is this code:

 #include <chrono>
 #include <future>
 #include <iostream>

 using namespace std::chrono_literals;

 int main()
 {
     try {
         std::atomic<bool> stopTask;
         stopTask.store(false, std::memory_order_seq_cst);

         auto future = std::async([&stopTask]() {
             for (int i = 0; i < 20; ++i)
             {
                 if (stopTask.load(std::memory_order_seq_cst))
                     break;
                 std::this_thread::sleep_for(500ms); // Imitation of useful task.
             }
         });

         // Some useful work in the main thread.
         throw std::runtime_error("Error"); // Oops! Something went wrong in the main thread.

         // Normal shutdown.
         stopTask.store(true, std::memory_order_seq_cst);
         future.get();
     }
     catch (...)
     {
         std::cout << "Exception caught" << std::endl;
     }
 }

I run a long-running task in a separate thread using std::async and receive std::future on it. And after that, an exception is thrown in the main thread. The stack unwinding begins and the destructors are called. As soon as it reaches the std::future destructor, stack unwinding stops and the main thread blocks until the second thread finishes.

It looks like that something is wrong. I have seen recommendations to make destructors as fast as possible and not to perform long operations in them. But here the destructor is very slow and stack unwinding takes a very long time.

Question: is it correct that stack unwinding takes so long? Maybe I'm doing something wrong and actually need to do something differently? What are the best practices in such cases?


In this particular code, the std::future destructor can be speeded up by making a wrapper class around std::atomic stopTask like RAII, which will set stopTask to true in the destructor. But it can still take up to 500 ms to execute the destructor. And this can no longer be speeded up, since in my application the real minimal operation takes so much time.

Why did compiler add static_cast to const rvalue ref if an object has a user defined/declared destructor

As per following example

struct Apple  {
  ~Apple() {};
};

int main()
{
    Apple a1;
    Apple a2 = std::move(a1);
}

and example

struct Apple  {
  ~Apple() = default;
};

int main()
{
    Apple a1;
    Apple a2 = std::move(a1);
}

with following transformation done by compiler

struct Apple
{
  inline ~Apple() /* noexcept */ = default;
  // inline constexpr Apple() noexcept = default;
  // inline constexpr Apple(const Apple &) noexcept = default;
};



int main()
{
  Apple a1;
  Apple a2 = Apple(static_cast<const Apple &&>(std::move(a1)));
  return 0;
}

compiler added static_cast<const Apple &&> in

Apple a2 = Apple(static_cast<const Apple &&>(std::move(a1)));

if there was a user defined/declared destructor. It was not the case as per example

struct Apple  {
};

int main()
{
    Apple a1;
    Apple a2 = std::move(a1);
}

where the transformed code snippet by compiler was

struct Apple
{
  // inline constexpr Apple() noexcept = default;
  // inline constexpr Apple(Apple &&) noexcept = default;
};



int main()
{
  Apple a1;
  Apple a2 = Apple(std::move(a1));
  return 0;
}

if no destructor is defined/declared by user.

Why was it the case?

PS People tends to think that it was because with user declared/defined destructor, compiler will only implicitly generate copy constructor but not move constructor. That is correct. But even only with copy constructor and without move constructor, const Apple& is able to be bound to rvalue ref and static_cast<const Apple&&> is not necessary for the code to compile, correct?

Is there a way to convert std::vector

The problem is I have a big vector contains big string contents fetched from local cache wrapped by shared_ptr:

std::vector<std::shared_ptr<std::string>>

but one of my library API requires:

void forExample(std::vector<std::string>& data);

In this library, the data will only be read, there is no modification, no memory operations, just read.

So how can I pass the data correctly without copying the big strings, or any other better recommendations? It's ok to change the library API signature if necessary.

dimanche 5 novembre 2023

Failed to install RcppArmadillo on Linux with OpenMP Error

I tried to install RcppArmadillo on a school Linux Hyper Cluster (which I do not have sudo access). I am installing via:

install.packages('RcppArmadillo')

in the R interface. The installation failed with the following error message:

using C++ compiler: ‘g++ (GCC) 4.8.5 20150623 (Red Hat 4.8.5-44)’
g++ -std=gnu++11 -I"/home/yz909/R/lib64/R/include" -DNDEBUG -I../inst/include -I'/cache/home/yz909/R/lib64/R/library/Rcpp/include' -I/usr/local/include   -fopenmp -fpic  -g -O2  -c RcppArmadillo.cpp -o RcppArmadillo.o
RcppArmadillo.cpp: In function ‘int armadillo_get_number_of_omp_threads()’:
RcppArmadillo.cpp:103:32: error: ‘omp_get_max_threads’ was not declared in this scope
     return omp_get_max_threads();
                                ^
RcppArmadillo.cpp: In function ‘void armadillo_set_number_of_omp_threads(int)’:
RcppArmadillo.cpp:113:26: error: ‘omp_set_num_threads’ was not declared in this scope
     omp_set_num_threads(n);
                          ^
make: *** [RcppArmadillo.o] Error 1
ERROR: compilation failed for package ‘RcppArmadillo’
* removing ‘/cache/home/yz909/R/lib64/R/library/RcppArmadillo’

The downloaded source packages are in
        ‘/tmp/Rtmpk3pNYK/downloaded_packages’
Warning message:
In install.packages("RcppArmadillo") :
  installation of package ‘RcppArmadillo’ had non-zero exit status

It seems to be a complier issue, could anyone help me with it?

I've tried both installing directly using

install.packages('RcppArmadillo')

and install using the github link, both yield to the same issue. My current R version is 4.3.1 and Rcpp version is 1.0.11.

why error in arduino but in atmega8 proteus does not matter

wiring.c.o (symbol from plugin): In function __vector_9': (.text+0x0): multiple definition of __vector_9' C:\Users\syste\AppData\Local\Temp\arduino\sketches\6F366EA3D470A87D93EB4DC2BC21772D\sketch\87segmentupdown.ino.cpp.o (symbol from plugin):(.text+0x0): first defined here collect2.exe: error: ld returned 1 exit status

exit status 1

Compilation error: exit status 1

Please help me, I hope it can be resolved quickly heheh

Different behaviour for normal and copy constructor [duplicate]

I have below code, when I remove the copy constructor in A, code compiles because I think default copy constructor is generated, which is public, so it gets called.

What I am trying to achieve is Prototype factory where I want to first create an object x and then replicate that object. I want to make sure that only Prototype factory is used to replicate the object and I don't want main() to call copy constructor in A directly. Anyone who wants to replicate has to use the factory dfunc(). How do I acheive this ?

Point to note here is that A(int, int) constructor gets called even if it is private, but strangely for copy constructor compiler complains that it is private.

#include <iostream>
#include <memory>
#include <string>
#include <utility>

using namespace std;

class A {
    friend ostream& operator<<(ostream& os, const A& aa);
    int a, b;

    A(int a, int b) : a(a), b(b) { cout << __PRETTY_FUNCTION__ << endl; }

    A(const A& aa) : a(aa.a), b(aa.b) { cout << __PRETTY_FUNCTION__ << endl; }

public:
    class C {
    public:
        static A cfunc(int x, int y) {
            cout << __PRETTY_FUNCTION__ << endl;
            return A{x, y};
        }
    };

    class D {
    public:
        static unique_ptr<A> dfunc(const A& aa) {
            cout << __PRETTY_FUNCTION__ << endl;
            return make_unique<A>(aa);
        }
    };
};

ostream& operator<<(ostream& os, const A& aa) {
    os << "(" << aa.a << "," << aa.b << ")";
    return os;
}

int main() {
    auto x = A::C::cfunc(10, 11);
    auto y = A::D::dfunc(x);

    cout << x << endl;
    cout << *y << endl;

    return 0;
}
test05.cpp:55:30: error: ‘A::A(const A&)’ is private within this context
   55 |   auto x = A::C::cfunc(10, 11);
      |                              ^
test05.cpp:19:3: note: declared private here
   19 |   A(const A& aa): a(aa.a), b(aa.b)
      |   ^
In file included from /usr/include/c++/9/memory:80,
                 from test05.cpp:3:
/usr/include/c++/9/bits/unique_ptr.h: In instantiation of ‘typename std::_MakeUniq<_Tp>::__single_object std::make_unique(_Args&& ...) [with _Tp = A; _Args = {const A&}; typename std::_MakeUniq<_Tp>::__single_object = std::unique_ptr<A>]’:
test05.cpp:41:31:   required from here
/usr/include/c++/9/bits/unique_ptr.h:857:30: error: ‘A::A(const A&)’ is private within this context
  857 |     { return unique_ptr<_Tp>(new _Tp(std::forward<_Args>(__args)...)); }
      |                              ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
test05.cpp:19:3: note: declared private here
   19 |   A(const A& aa): a(aa.a), b(aa.b)
      |   ^

samedi 4 novembre 2023

My VScode cannot initialize strings created dynamically using 'new'.What is the wrong?

my code:

#include<iostream>
using namespace std;


int main()
{
    char * ar1 = new char[3] {'a','b','\0'};
    char * ar2 = new char[3] {"ab"};
    const char * ar3 =new char[3]{"ab"};
    cout << ar1 << endl;
    cout << ar2;
    cin.get();
    return 0;
}

Ar1 can be initialized successfully, but ar2 and ar3 cannot. What is the error?

At first, I thought my compiler didn't support C++11, but I found that it could initialize ar1, indicating that it was supported, so I'm confused now.

declaring a non static function that takes a variable amount of arguments and then using defining it in the constructor

I have a Button class where each instance will have its callback function with a variable amount of arguments.

*Button.hpp*
class Button{
    private:
        static unsigned short width;
        static unsigned short height;

        sf::RectangleShape* buttonArea;
        std::string text;
        int x,y;
        
        std::function<void()> callback;

    public:
        //Constructors and Destructors
        template <typename ...Args>
        Button(std::string text,std::function<void()> callback ,Args... args);

        
        ~Button();

        bool isClicked(sf::Vector2i pos);

        void onClick();

*Button.cpp*
template <typename ...Args>
Button::Button(std::string text, std::function<void()> callback, Args... args){
    width = 10;
    height = 10;

    this->text = text;

    this->buttonArea = new sf::RectangleShape(sf::Vector2f(width,height));

    this->callback = std::bind(callback, ..args);

};

void onClick(){
    if(this->callback)
        callback();
}

};

The Error appears on onClick where it says 'this' may only be used inside a nonstatic member functionC/C++(258)

Perhaps the use of bind is wrong or the declaration of callback

c++11 I can not initialize a member with '()' while i can use '{}' to do this? [duplicate]

#pragma once
#include <list>
#include <unordered_map>
template<typename K, typename V>
class LRUCache
{
public:
    LRUCache(size_t _capcity):capcity(_capcity)
    {   
    }
    ~LRUCache()
    {
    
    }
    void put(K key ,V value)
    {
        if (dic.count(key))
        {
            auto it = dic[key];
            *it = { key, value };
            data.splice(data.begin(), data, it);
        }
        else
        {
            data.push_front({ key, value });
            dic[key] = data.begin();
        }
        while (data.size() > capcity)
        {
            dic.erase(data.back().first);
            data.pop_back();
        }
    }

    V get(K key)
    {
        if (!dic.count(key)) return -1;
        auto it = dic[key];
        data.splice(data.begin(), data, it);
        return it->second;
    }


private:
    size_t  capcity;
    std::list<std::pair<K, V>> data;
    std::unordered_map<K, typename std::list<std::pair<K, V>>::iterator> dic;
};

This class has a constructor with initial list.

#pragma once
#include "LRUCache.h"

class SLRU
{
public:
    SLRU();
    ~SLRU();

private:
    LRUCache<std::string, int> protectLRU{ 10 };
    LRUCache<std::string, int> eliminateLRU{ 10 };

};

SLRU::SLRU()
{
}

SLRU::~SLRU()
{
}

this class wants to initialize a LRUCache member.

i find that if the LRUCache's constructor has no initial list

    LRUCache(size_t _capcity)
    {   
           capcity = _capcity;
    }

i can use '()' to initialize the LRUCache member

LRUCache<std::string, int> eliminateLRU(10);

otherwise, i can not use '()'. so what magic does '{}‘ has betwen it and initial list? where can i find the answer when meeting the problem like it?

vendredi 3 novembre 2023

I need a way of parsing C file's contents, including #if macros [closed]

I'm working on a converter that can convert old assets declared in c to some new formats. I decided to once more do research on this, so far my options look... limited... also a lot of old websites. Ideally I'd like something that keeps it simple-ish, can handle macros properly (including #if, #ifdef and other conditionals), etc. There is some stuff I think I'll have to handle myself in some way but I'm ok with thinking about all that as needed. Right now I just want to know what my options are for my c++ (c++11 specifically, because of tiny_glTF) project. Aside from a library/tool/method I honestly just want some suggestions on what I should do, what I could use and just general comment. Thank you for reading all of this!

I attempted to write my own parsers in the past and while I'd say my latest attempt was pretty good (to some extent) handling specific edge cases feels very unsafe (and my previous attempt was lost because of some weird wsl behavior? lesson learned about not committing frequently aha), it also broke with functions which while I don´t really need to parse right now I might in the future and they were hard to ignore.