vendredi 30 juin 2023

Using opencv processing (cv::imshow cv::cvtColor) in Gstreamer application (appsink)

I want to use appsink to extract the frames in the Gstbuffer in the pipeline, and then use opencv for image processing, I refer to the program in this link (Adding opencv processing to gstreamer application), but when I use imshow or cvtColor in the main function, there will be a core dump error, But in the new_sample function, I should have successfully extracted each frame in the buffer, and the map.size is also correct (BGR, width=100, height=100, map.size=30000).

opencv version:4.7.0

video/x-raw, format=(string)BGR, width=(int)100, height=(int)100, framerate=(fraction)30/1, multiview-mode=(string)mono, pixel-aspect-ratio=(fraction)1/1, interlace-mode=(string)progressive Erreur de segmentation (core dumped)

Gtk-Message: 17:04:05.146: Failed to load module "appmenu-gtk-module" frameSize: 30000 video/x-raw, format=(string)BGR, width=(int)100, height=(int)100, framerate=(fraction)30/1, multiview-mode=(string)mono, pixel-aspect-ratio=(fraction)1/1, interlace-mode=(string)progressive frameSize: 30000 Erreur de segmentation (core dumped)

#include <gst/gst.h>
#include <gst/app/app.h>
#include <gst/app/gstappsink.h>
#include <stdlib.h> 
#include <opencv2/opencv.hpp>
#include <opencv2/core.hpp>
#include <opencv2/videoio.hpp>
#include <opencv2/highgui.hpp>
using namespace cv;

// TODO: use synchronized deque
std::deque<Mat> frameQueue;

 

GstFlowReturn
new_preroll(GstAppSink *appsink, gpointer data) {
  g_print ("Got preroll!\n");
  return GST_FLOW_OK;
}

 

GstFlowReturn
new_sample(GstAppSink *appsink, gpointer data) {
  static int framecount = 0;
  framecount++;

 

  GstSample *sample = gst_app_sink_pull_sample(appsink);
  GstCaps *caps = gst_sample_get_caps(sample);
  GstBuffer *buffer = gst_sample_get_buffer(sample);
  const GstStructure *info = gst_sample_get_info(sample);

 

  // ---- Read frame and convert to opencv format ---------------
  GstMapInfo map;
  gst_buffer_map (buffer, &map, GST_MAP_READ);
  // convert gstreamer data to OpenCV Mat, you could actually
  // resolve height / width from caps...
  Mat frame(Size(320, 240), CV_8UC3, (char*)map.data, Mat::AUTO_STEP);
  int frameSize = map.size;
  g_print ("frameSize: %d\n",frameSize);
  // TODO: synchronize this....
  frameQueue.push_back(frame);
  gst_buffer_unmap(buffer, &map);

  // ------------------------------------------------------------
  // print dot every 30 frames
  if (framecount%30 == 0) {
    g_print (".");
  }

  // show caps on first frame
  if (framecount == 1) {
    g_print ("%s\n", gst_caps_to_string(caps));
  }
  gst_sample_unref (sample);
  return GST_FLOW_OK;
}

 

static gboolean
my_bus_callback (GstBus *bus, GstMessage *message, gpointer data) {
  g_print ("Got %s message\n", GST_MESSAGE_TYPE_NAME (message));
  switch (GST_MESSAGE_TYPE (message)) {
    case GST_MESSAGE_ERROR: {
      GError *err;
      gchar *debug;

 

      gst_message_parse_error (message, &err, &debug);
      g_print ("Error: %s\n", err->message);
      g_error_free (err);
      g_free (debug);    
      break;
    }
    case GST_MESSAGE_EOS:
      /* end-of-stream */
      break;
    default:
      /* unhandled message */
      break;
  }
  /* we want to be notified again the next time there is a message
   * on the bus, so returning TRUE (FALSE means we want to stop watching
   * for messages on the bus and our callback should not be called again)
   */
  return TRUE;
}

 

int
main (int argc, char *argv[])
{
  GError *error = NULL;

 

  gst_init (&argc, &argv);

 

  gchar *descr = g_strdup(
    "videotestsrc  pattern=ball ! "
    "video/x-raw,width=100,height=100,format=(string)BGR ! "
    "videoconvert ! "
    "appsink name=sink sync=true"
  );
  GstElement *pipeline = gst_parse_launch (descr, &error);

 

  if (error != NULL) {
    g_print ("could not construct pipeline: %s\n", error->message);
    g_error_free (error);
    exit (-1);
  }


  /* get sink */
  GstElement *sink = gst_bin_get_by_name (GST_BIN (pipeline), "sink");

  gst_app_sink_set_emit_signals((GstAppSink*)sink, true);
  gst_app_sink_set_drop((GstAppSink*)sink, true);
  gst_app_sink_set_max_buffers((GstAppSink*)sink, 1);
  GstAppSinkCallbacks callbacks = { NULL, new_preroll, new_sample };
  gst_app_sink_set_callbacks (GST_APP_SINK(sink), &callbacks, NULL, NULL);


  GstBus *bus;
  guint bus_watch_id;
  bus = gst_pipeline_get_bus (GST_PIPELINE (pipeline));
  bus_watch_id = gst_bus_add_watch (bus, my_bus_callback, NULL);
  gst_object_unref (bus);

 
  gst_element_set_state (GST_ELEMENT (pipeline), GST_STATE_PLAYING);
  namedWindow("edges",1);
  while(1) {
    g_main_iteration(false);

      // TODO: synchronize...
    if (frameQueue.size() > 0) {
      // this lags pretty badly even when grabbing frames from webcam
      Mat frame = frameQueue.front();
      Mat edges;
      cvtColor(frame, edges, cv::COLOR_BGR2GRAY);
      //GaussianBlur(edges, edges, Size(7,7), 1.5, 1.5);
      //Canny(edges, edges, 0, 30, 3);
      //imshow("edges", edges);
      //cv::waitKey(30);
      frameQueue.clear();
    }
  }  

  gst_element_set_state (GST_ELEMENT (pipeline), GST_STATE_NULL);
  gst_object_unref (GST_OBJECT (pipeline));

I'm a newbie and would appreciate some help, many thanks!

Template queue with pre defined size

I want something like this: Queue<type, size> my_queue;. Here the typeis whatever I want. It can be an array, a structure or something else. Size is the maximum allowed elements that my_queue object can contain. From this thread I understand that I must have a wrapper class that allows me to set a size value and access to the actual queue through the wrapper class. But I also must be able to instantiate a Queue object with different types.

So I thought I can solve my problem by using templates. My only constraint is limiting the Queue size in order to limit the dynamically allocated memory by the std::queue. I thought I can inherit from the std::queue and simply create a class like this:

template<typename T>
class Queue final : public std::queue<T> {
public:
    Queue(T type, uint32_t size) : size_(size) { };

    virtual ~Queue() = default;

    bool push(T new_element) {
        if(this->size() < size_) {
            this->push(new_element);
            return 1;
        }
        return 0;
    }
    ;

private:
    const uint32_t size_ = 0;
};

This is compiling. But I know it is not correct. I do not know how can I do it. Also when I want to create an instance of Queue like Queue<uint8_t[5], 5> my_queue; it does not compile.

jeudi 29 juin 2023

Unexpected output when invoking overloaded functions with different rvalue reference types

I'm encountering an unexpected behavior in my code when calling overloaded functions with different rvalue reference types. The code snippet below demonstrates the issue:

#include <iostream>

void foo(int&& x)
{
    std::cout << "int Rvalue: " << x << std::endl;
}

void foo(float&& x)
{
    std::cout << "float Rvalue: " << x << std::endl;
}

int main()
{
    int int_x = 1;
    float float_x = 5.14f;

    foo(int_x);
    foo(float_x);
}

Output

float Rvalue: 1
int Rvalue: 5

Instead of getting the anticipated output, which should be "int Rvalue: 1" and "float Rvalue: 5", I observe the reverse order. I find this behavior perplexing and would appreciate insights into why this is happening.

I have made sure to understand the concept of rvalue references and how overloading works based on them. I have also tried to search for similar issues, but haven't found any that directly address this specific situation.

Any guidance or explanations would be greatly appreciated. Thank you in advance for your assistance!

multithread std::shared_ptr read / write with sigsegv

a global shared_ptr g_ptr=null; then in thread 1, call init() set g_ptr=make_shared();

after that, has other thread x use write()


void write()
{
   if(g_ptr)
   {
       g_ptr->dosomething();// g_ptr.get() has a std::FILE _fd;
    }
}

then the program end. the program is

in thread 1, the global g_ptr has destory. but in other thread, func write is doing,but the _fd is set to nullptr. so the program segmentaion fault.

both init() and write() are interface, called by customer.

how can i avoid this program? use the raw pointer and provide a close() api ,may be ok. except this, how can i resolve this program with use smart pointer。 thanks.

In Qt c QLabel::setText does not work but other fun can work

I wanted to display the specified content in the label (Client::saveData, a static variable),but I couldn't do it anyway. QMessageBox::information works, and qDebug() outputs the correct content, but it just doesn't show up on the label.

void S8524Widget::setTandHLabel()
{
    qDebug() << Client::saveData;

    QMessageBox::information(NULL,"OK","OK");
    ui->tempText->setAlignment(Qt::AlignCenter);
    QString tempdata(Client::saveData.left(2));
    ui->tempText->setText(tempdata);
    //ui->tempText->setProperty("text",tempdata);
    //ui->tempText->setStyleSheet("setProperty: TEST;");
    QString var = ui->tempText->text();

    QString humiditydata(Client::saveData.right(2));
    ui->humidityText->setText(humiditydata);
    QString vae = ui->humidityText->text();

    ui->ProgramNameText->setPlainText(tempdata);
    ui->TimeStatusText->setPlainText(tempdata);
    ui->StepStatusText->setPlainText(tempdata);

    qDebug() << var;
    qDebug() << vae;
}

Client::saveData prints correctly. If I put settext in the constructor, it works fine, but I need it to update the text dynamically. In this function, even setText (“Tempdata”) doesn't work. If you save Ui-> tempText as a variable, calling setText from the mainwindow won't work either.

mercredi 28 juin 2023

Use a Polygon in Boost RTree?

I'm using an RStar tree for a project and there is a need to move to a shape that is not axis aligned. The current implementation (and documentation example) uses box, which is defined by two points and so is always axis aligned. I still want boxes but they need to be able go diagonally through the space while being narrow. My first thought was to use polygon and specify the 8 vertices all manually. However, when I try and create a tree of this type it says Polygon is not indexable. I looked at the box documentation (and Point) and don't see the indexable property there so I'm not sure which objects have it or how to implement it myself. Has anyone else done this before?

RTree Example: https://www.boost.org/doc/libs/1_82_0/libs/geometry/doc/html/geometry/spatial_indexes/rtree_quickstart.html

Box Documentation (constructed via only two points): https://www.boost.org/doc/libs/1_82_0/libs/geometry/doc/html/geometry/reference/models/model_box.html

Polygon (that I want to use): https://www.boost.org/doc/libs/1_82_0/boost/geometry/geometries/polygon.hpp

Example code with parts that don't compile commented out (just to show the gist of what I want, the goal was to write code the performed exactly the same as the example but using a shape I had more control over):

#include <iostream>
#include <vector>
#include <boost/assign/std/vector.hpp>
#include <boost/geometry.hpp>
#include <boost/geometry/algorithms/area.hpp>
#include <boost/geometry/algorithms/assign.hpp>
#include <boost/geometry/geometries/point_xy.hpp>
#include <boost/geometry/geometries/polygon.hpp>
#include <boost/geometry/io/dsv/write.hpp>

#include <boost/geometry/index/rtree.hpp>

int main()
{
    using namespace boost::assign;
    namespace bg = boost::geometry;
    namespace bgi = boost::geometry::index;

    typedef bg::model::d2::point_xy<float> point;
    typedef bg::model::polygon<point> polygon2d;
    typedef std::pair<polygon2d , unsigned> value;

    // create the rtree using default constructor
//    bgi::rtree< value, bgi::quadratic<16> > rtree;

    // create some values
    for ( unsigned i = 0 ; i < 10 ; ++i )
    {
        // create a polygon that's the same as the box in the online example
        // https://www.boost.org/doc/libs/1_72_0/libs/geometry/doc/html/geometry/spatial_indexes/rtree_quickstart.html
        std::vector<point> points;
        points +=
                point(i + 0.0f, i + 0.0f),
                point(i + 0.0f, i + 0.5f),
                point(i + 0.5f, i + 0.0f),
                point(i + 0.5f, i + 0.5f)
                ;

        polygon2d p;
        bg::assign_points(p, points);
//        // insert new value
//        rtree.insert(std::make_pair(p, i));
    }

    // find values intersecting some area defined by a box
    polygon2d query_box;
    std::vector<point> query_points;
    query_points +=
            point(0, 0),
            point(0, 5),
            point(5, 0),
            point(5, 5)
            ;
    bg::assign_points(query_box, query_points);
//    std::vector<value> result_s;
//    rtree.query(bgi::intersects(query_box), std::back_inserter(result_s));
//
//    // find 5 nearest values to a point
//    std::vector<value> result_n;
//    rtree.query(bgi::nearest(point(0, 0), 5), std::back_inserter(result_n));
//
//    // display results
//    std::cout << "spatial query box:" << std::endl;
//    std::cout << bg::wkt<box>(query_box) << std::endl;
//    std::cout << "spatial query result:" << std::endl;
//    BOOST_FOREACH(value const& v, result_s)
//    std::cout << bg::wkt<box>(v.first) << " - " << v.second << std::endl;
//
//    std::cout << "knn query point:" << std::endl;
//    std::cout << bg::wkt<point>(point(0, 0)) << std::endl;
//    std::cout << "knn query result:" << std::endl;
//    BOOST_FOREACH(value const& v, result_n)
//    std::cout << bg::wkt<box>(v.first) << " - " << v.second << std::endl;
}


mutable data member template constructor and trivially copy constructible

Example code could be found below or on godbolt. Say we have 4 classes:

  1. S<T>: holding a data member.

  2. SCtor<T>: holding a data member and has a template constructor.

  3. SCtorMutable<T>: holding a mutable data member and has a template constructor.

  4. SCtorDefault<T>: holding a member, has a template constructor, has defaulted copy/move constructors and defaulted copy/move assignment operators.

All compilers agree that these 4 classes are trivially copyable.

If there is a simple wrapper class W<T> holding any of the above class as a data member. The wrapper class W<S...<T>> is still trivially copyable.

If there is another wrapper class WMutable<T> holding any of the above class as a mutable data member.

  1. MSVC still believes WMutable<S...<T>> is trivially copyable.
  2. clang believes WMutable<S<T>> is trivially copyable. WMutable<SCtor...<T>> is not trivially copy constructible therefore not trivially copyable.
  3. gcc believes WMutable<S<T>> is trivially copyable. WMutable<SCtor...<T>> is not trivially copy constructible BUT trivially copyable.

Should WMutable<T> be trivially copyable?

#include <type_traits>
#include <utility>

template<typename T>
struct S {
    T m_t;
};

template<typename T>
struct SCtor {
    T m_t;
    template<typename... U>
    SCtor(U&&... u): m_t(std::forward<U>(u)...) {}
};

template<typename T>
struct SCtorMutable {
    mutable T m_t;
    template<typename... U>
    SCtorMutable(U&&... u): m_t(std::forward<U>(u)...) {}
};

template<typename T>
struct SCtorDefault {
    T m_t;
    template<typename... U>
    SCtorDefault(U&&... u): m_t(std::forward<U>(u)...) {}
    SCtorDefault(SCtorDefault const&) = default;
    SCtorDefault(SCtorDefault&&) = default;
    SCtorDefault& operator=(SCtorDefault const&) = default;
    SCtorDefault& operator=(SCtorDefault&&) = default;
};

template<typename T>
struct W {
    T m_t;
};

template<typename T>
struct WMutable {
    mutable T m_t;
};

static_assert(std::is_trivially_copyable<S<int>>::value);
static_assert(std::is_trivially_copy_constructible<S<int>>::value);
static_assert(std::is_trivially_move_constructible<S<int>>::value);
static_assert(std::is_trivially_copy_assignable<S<int>>::value);
static_assert(std::is_trivially_move_assignable<S<int>>::value);

static_assert(std::is_trivially_copyable<SCtor<int>>::value);
static_assert(std::is_trivially_copy_constructible<SCtor<int>>::value);
static_assert(std::is_trivially_move_constructible<SCtor<int>>::value);
static_assert(std::is_trivially_copy_assignable<SCtor<int>>::value);
static_assert(std::is_trivially_move_assignable<SCtor<int>>::value);

static_assert(std::is_trivially_copyable<SCtorMutable<int>>::value);
static_assert(std::is_trivially_copy_constructible<SCtorMutable<int>>::value);
static_assert(std::is_trivially_move_constructible<SCtorMutable<int>>::value);
static_assert(std::is_trivially_copy_assignable<SCtorMutable<int>>::value);
static_assert(std::is_trivially_move_assignable<SCtorMutable<int>>::value);

static_assert(std::is_trivially_copyable<SCtorDefault<int>>::value);
static_assert(std::is_trivially_copy_constructible<SCtorDefault<int>>::value);
static_assert(std::is_trivially_move_constructible<SCtorDefault<int>>::value);
static_assert(std::is_trivially_copy_assignable<SCtorDefault<int>>::value);
static_assert(std::is_trivially_move_assignable<SCtorDefault<int>>::value);

static_assert(std::is_trivially_copyable<W<S<int>>>::value);
static_assert(std::is_trivially_copy_constructible<W<S<int>>>::value);
static_assert(std::is_trivially_move_constructible<W<S<int>>>::value);
static_assert(std::is_trivially_copy_assignable<W<S<int>>>::value);
static_assert(std::is_trivially_move_assignable<W<S<int>>>::value);

static_assert(std::is_trivially_copyable<W<SCtor<int>>>::value);
static_assert(std::is_trivially_copy_constructible<W<SCtor<int>>>::value);
static_assert(std::is_trivially_move_constructible<W<SCtor<int>>>::value);
static_assert(std::is_trivially_copy_assignable<W<SCtor<int>>>::value);
static_assert(std::is_trivially_move_assignable<W<SCtor<int>>>::value);

static_assert(std::is_trivially_copyable<W<SCtorMutable<int>>>::value);
static_assert(std::is_trivially_copy_constructible<W<SCtorMutable<int>>>::value);
static_assert(std::is_trivially_move_constructible<W<SCtorMutable<int>>>::value);
static_assert(std::is_trivially_copy_assignable<W<SCtorMutable<int>>>::value);
static_assert(std::is_trivially_move_assignable<W<SCtorMutable<int>>>::value);

static_assert(std::is_trivially_copyable<W<SCtorDefault<int>>>::value);
static_assert(std::is_trivially_copy_constructible<W<SCtorDefault<int>>>::value);
static_assert(std::is_trivially_move_constructible<W<SCtorDefault<int>>>::value);
static_assert(std::is_trivially_copy_assignable<W<SCtorDefault<int>>>::value);
static_assert(std::is_trivially_move_assignable<W<SCtorDefault<int>>>::value);

static_assert(std::is_trivially_copyable<WMutable<S<int>>>::value);
static_assert(std::is_trivially_copy_constructible<WMutable<S<int>>>::value);
static_assert(std::is_trivially_move_constructible<WMutable<S<int>>>::value);
static_assert(std::is_trivially_copy_assignable<WMutable<S<int>>>::value);
static_assert(std::is_trivially_move_assignable<WMutable<S<int>>>::value);

static_assert(std::is_trivially_copyable<WMutable<SCtor<int>>>::value); // error with clang
static_assert(std::is_trivially_copy_constructible<WMutable<SCtor<int>>>::value); // error with clang/gcc
static_assert(std::is_trivially_move_constructible<WMutable<SCtor<int>>>::value);
static_assert(std::is_trivially_copy_assignable<WMutable<SCtor<int>>>::value);
static_assert(std::is_trivially_move_assignable<WMutable<SCtor<int>>>::value);

static_assert(std::is_trivially_copyable<WMutable<SCtorMutable<int>>>::value); // error with clang
static_assert(std::is_trivially_copy_constructible<WMutable<SCtorMutable<int>>>::value); // error with clang/gcc
static_assert(std::is_trivially_move_constructible<WMutable<SCtorMutable<int>>>::value);
static_assert(std::is_trivially_copy_assignable<WMutable<SCtorMutable<int>>>::value);
static_assert(std::is_trivially_move_assignable<WMutable<SCtorMutable<int>>>::value);

static_assert(std::is_trivially_copyable<WMutable<SCtorDefault<int>>>::value); // error with clang
static_assert(std::is_trivially_copy_constructible<WMutable<SCtorDefault<int>>>::value); // error with clang/gcc
static_assert(std::is_trivially_move_constructible<WMutable<SCtorDefault<int>>>::value);
static_assert(std::is_trivially_copy_assignable<WMutable<SCtorDefault<int>>>::value);
static_assert(std::is_trivially_move_assignable<WMutable<SCtorDefault<int>>>::value);

mardi 27 juin 2023

C string find always returning not found [closed]

I'm trying to find a string in a vector of strings. So I'm doing

vector<int> exists(vector<string>G, int row, int column, string p){
    vector<int>pos;  
    for(int i = row; i < G.size() ; i++){
        string x = G[i];
        if(x.find(p) != std::string::npos){
            if(row == 0){
                pos.push_back(i);
                pos.push_back(x.find(p));
            }
            else {
                if(x.find(p) == column){
                    pos.push_back(i);
                    pos.push_back(x.find(p));
                }
            }
            return pos;
        }
    }
    
    return pos;
}

For example I've this gird: 1234567890
0987654321
1111111111
1111111111
2222222222

and I'm trying to find 876543

But find() is always returning std::string::npos. Is there something wrong here or should be done differently?

QT6 QAudioProbe no more

I was trying to replicate the Media player example provided. While it is possible to create an audio meter using QAudioProbe in Qt5, I am unable to figure out how to achieve the same in Qt6.

I have created a custom QWidget called VMeterWidget, which represents the vertical meter widget. It has a setLevel() function to set the meter level, an updateAudioLevel() function to update the level based on the peak value, and a paintEvent() function to paint the widget.

The VMeterWidget also includes a QTimer for periodic level resets and an updateLevel() slot for smooth level transitions. The paintEvent() function uses QPainter to draw the meter with a gradient color scheme.

I'm facing challenges in finding an alternative to QAudioProbe in Qt6 to capture and analyze audio data for the meter. Any assistance or guidance on how to achieve this functionality in Qt6 would be greatly appreciated.

I share the code for the audio meter.

#include <QWidget>
#include <QPainter>

class VMeterWidget : public QWidget
{
    Q_OBJECT
public:
    explicit VMeterWidget(QWidget *parent = nullptr);

    // Imposta il livello del meter (compreso tra 0 e 1)
    void setLevel(qreal level);
    void updateAudioLevel(qreal peak);

protected:
    void paintEvent(QPaintEvent *event);

private:
    qreal m_level;
    qreal targetLevel;
    const qreal maxValue = 1.2;
    QTimer *resetTimer;
    bool isUpdatingLevel = false;


private slots:
    void resetLevel();
    void updateLevel();
};

and this is the cpp file

#include "vuMeter.h"
#include "qtimer.h"
#include <QDebug>

VMeterWidget::VMeterWidget(QWidget *parent)
    : QWidget(parent), m_level(0)
{
    setMinimumSize(20, 100);
    // Crea un timer per il reset periodico
    resetTimer = new QTimer(this);
    connect(resetTimer, SIGNAL(timeout()), this, SLOT(resetLevel()));

    // Imposta l'intervallo del timer (ad esempio, 1 secondo)
    int resetInterval = 500; // Tempo in millisecondi
    resetTimer->setInterval(resetInterval);
    resetTimer->start();
}

void VMeterWidget::setLevel(qreal level)
{
    if (m_level != level) {
        isUpdatingLevel = true;
        targetLevel = level;
        updateLevel();
    }
}

void VMeterWidget::updateLevel()
{
    qreal step = 0.08; // Passo di incremento per ogni iterazione del ciclo
    qreal diff = targetLevel - m_level;
    if (qAbs(diff) > step) {
        if (diff > 0) {
            m_level += step;
        } else {
            m_level -= step;
        }
        update();
        QTimer::singleShot(10, this, SLOT(updateLevel()));
    } else {
        m_level = targetLevel;
        isUpdatingLevel = false;
        update();
    }

}

void VMeterWidget::paintEvent(QPaintEvent *event)
{
    Q_UNUSED(event);

    QPainter painter(this);
    painter.setRenderHint(QPainter::Antialiasing);

    // Sfondo del widget
    painter.fillRect(rect(), Qt::black);

    // Area del meter
    QRectF meterRect = QRectF(0, height() * (1 - m_level), width(), height() * m_level);

    // Gradiente per il meter
    QLinearGradient gradient(meterRect.topLeft(), meterRect.bottomLeft());

    // Imposta il colore per i primi 5 punti percentuali
    gradient.setColorAt(0, Qt::red);
    gradient.setColorAt(0.001, Qt::darkRed);
    gradient.setColorAt(0.02, Qt::darkYellow);
    gradient.setColorAt(0.03, Qt::yellow);
    gradient.setColorAt(0.04, Qt::darkGreen);

    // Imposta il colore per l'ultimo punto percentuale
    gradient.setColorAt(1, Qt::green);

    // Disegna il meter
    painter.fillRect(meterRect, gradient);
}


void VMeterWidget::updateAudioLevel(qreal peak)
{
    // Normalizza il valore del picco tra 0 e 1
    qreal level = peak / maxValue;

    // Imposta il livello del meter
    setLevel(level);

    // Resetta il timer per evitare il reset del livello
    // se viene ricevuto un nuovo picco audio entro l'intervallo
    resetTimer->start();
}

void VMeterWidget::resetLevel()
{
    setLevel(0);
}

lundi 26 juin 2023

const std::string::size() is much larger than it should be in optimization level 2

Definition:

const std::string a_class::dft_col_name{"NONE"};

Usage:

in a_class::function()

just loop one time, i is 0

for (int i = 0; i < result->colnum; ++i) {
    result->pcolname[(i + 1) * SQLCOLLEN - 1] = '\0';
    auto colname_len = strlen(result->pcolname + i * SQLCOLLEN);
    if (colname_len == 0) {
        // given column name if there isn't
        strcpy(result->pcolname + i * SQLCOLLEN, dft_col_name.c_str());
        colname_len = dft_col_name.size();

        /*!! Confusion !!*/

        std::cout << dft_col_name << '\n';
        // O2 print: lots of corrupted text
        std::cout << dft_col_name.c_str() << '\n';
        // O2 print: "NONE"
        printf("%lu %lu %s\n", colname_len, dft_col_name.size(), dft_col_name.c_str());
        // -g O0 print: 4 4 NONE
        // O2 print: 17179869184 17179869184 NONE

    }
    result->plen[i] = colname_len;
}

Environment:

Linux version 3.10.0-1062.12.1.el7.x86_64 (mockbuild@kbuilder.bsys.centos.org)
(gcc version 4.8.5 20150623 (Red Hat 4.8.5-39) (GCC) ) #1 SMP Tue Feb 4 23:02:59 UTC 2020

g++ (GCC) 4.8.5 20150623 (Red Hat 4.8.5-44)
Copyright (C) 2015 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

I'm really confused about it!

I tried using valgrind --tool=memcheck to debug, and no Invalid write was found.

I tried relacing const std::string to const char[], dft_col_name.size() to strlen(), and it worked.

I am trying to create a program that outputs to screen and to file but when outputting to screen I keep getting a (-) number rather than decimal?

I am supposed to create two "functions" and one is to print the total resistance in parallel to the screen. I have tried looking up the difference between using integer division and float division but when dividing the number 1 over the sum of the resistors, it gives me the result of "inf". When changing one of the variables to an integer, the variable gives me a long - number. versus the result I am looking for. The answer I get on a calculator is 0.02316 but when switching the double for the integer I get -2147483648.

#include <iostream>
#include <fstream>
#include <iomanip>
~~~~~~~~~~~~~~~~~~~~~~~~~
using namespace std;
~~~~~~~~~~~~~~~~~~~~~~~
//create vector for resistor
//create variable for resistors
//create variable for equation in parallel
//output string with precision and results
//create variable for equation in series
//output string with precision and results
~~~~~~~~~~~~~~~~~
int main() {
    ifstream in_file;
    double resistor1, resistor2, resistor3, resistor4, resistor5, resistor6;
    double resistors_in_series;
    int resistors_in_parallel;
    
    in_file>> resistor1>>resistor2>>resistor3>>resistor4>>resistor5>>resistor6;
    resistors_in_parallel = 1.0/(resistor1+resistor2+resistor3+resistor4+resistor5+resistor6);
    cout << "The total equivalent resistance is " << fixed <<setprecision(1) << resistors_in_parallel << " ohms if resistors are connected in parallel." << endl;
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~ 
    ofstream out_file;
        
    in_file.open("resistors.txt");
    out_file.open("total_resistance.txt");
    
    out_file<<fixed<< setprecision(1);
    
    in_file>> resistor1>>resistor2>>resistor3>>resistor4>>resistor5>>resistor6;
    resistors_in_series = (resistor1+resistor2+resistor3+resistor4+resistor5+resistor6);
    out_file<< "The total equivalent resistance is "<< resistors_in_series << " ohms if resistors are connected in series.";
    
    in_file.close();
    out_file.close();
}
~~~~~~~~~~~~~~~~~~~~~~~

dimanche 25 juin 2023

Does clang add getters/setter methods in the generated bytecode for C?

I added new fields + get_*/set_* methods to my struct in the header file, but didn't (cause I forgot) add the simple implementation in the cc file.

I compiled my code with clang and it didn't show any errors. I immediately realized that I didn't add the implementation for the get_*/set_* methods and then wondered why the compiler didn't complain.

Is clang adding these get/set methods in the bytecode on its own?

Thanks!

When does the default copy assignment operator from C11 utilize bit-wise copy instead of member-wise copy?

In both x86-64 GCC 13.1 and Clang 16.0.0, the copy<PrivateBase> function uses member-wise copy, while the copy<PublicBase> function uses bit-wise copy. You could refer to the detailed source code and assembly code on the compiler explorer or see the code snippets provided below:

class PublicBase {
public:
    int num;
    char c1;
};

class PrivateBase {
private:
    int num;
    char c1;
};


template<typename T>
__attribute_noinline__ void copy(T *dst, T *src) {
    *dst = *src;
}

template void copy(PublicBase *dst, PublicBase *src);
template void copy(PrivateBase *dst, PrivateBase *src);
void copy<PublicBase>(PublicBase*, PublicBase*):
        mov     rax, QWORD PTR [rsi]
        mov     QWORD PTR [rdi], rax
        ret
void copy<PrivateBase>(PrivateBase*, PrivateBase*):
        mov     eax, DWORD PTR [rsi]
        mov     DWORD PTR [rdi], eax
        movzx   eax, BYTE PTR [rsi+4]
        mov     BYTE PTR [rdi+4], al
        ret

The question is, when does the default copy assignment operator from C++11 use bit-wise copy instead of member-wise copy? It seems that neither is_trivially_copyable nor is_pod provides the answer.

is_trivially_copyable

According to cppreference-is_trivially_copyable:

Objects of trivially-copyable types that are not potentially-overlapping subobjects are the only C++ objects that may be safely copied with std::memcpy.

Both PublicBase and PrivateBase are trivially copyable and not subobjects, but PrivateBase is copied with member-wise instead of bit-wise.

is_pod

If there is a derived class of PublicBase or PrivateBase, the derived class of PrivateBase will reuse the padding of the base class, while that of PublicBase won't.

Therefore, it is reasonable that PrivateBase is copied with member-wise. Otherwise, the padding of base class may overwrite PrivateDerived::c2 when calling copy<PrivateBase>(derived, base).


class PublicDerived : public PublicBase {
public:
    char c2;
};

class PrivateDerived : public PrivateBase {
private:
    char c2;
};


int main() {
    std::cout << "sizeof(PublicBase)=" << sizeof(PublicBase) << std::endl;
    std::cout << "sizeof(PublicDerived)=" << sizeof(PublicDerived) << std::endl;
    std::cout << "sizeof(PrivateBase)=" << sizeof(PrivateBase) << std::endl;
    std::cout << "sizeof(PrivateDerived)=" << sizeof(PrivateDerived) << std::endl;

    return 0;
}
// Output:
// sizeof(PublicBase)=8
// sizeof(PublicDerived)=12
// sizeof(PrivateBase)=8
// sizeof(PrivateDerived)=8

I am confused about how the compiler decides to reuse padding of the base class or not. According to the related question, the POD type doesn't reuse padding of the base class.

According to the cppreference-POD_class:

A POD class is a class that

  • until C++11:
    • is an aggregate (no private or protected non-static data members),
    • has no user-declared copy assignment operator,
    • has no user-declared destructor, and
    • has no non-static data members of type non-POD class (or array of such types) or reference.
  • since C++11
    • is a trivial class,
    • is a standard-layout class (has the same access control for all non-static data members), and
    • has no non-static data members of type non-POD class (or array of such types).

before C++11, PrivateBase is not POD type (because it has private data members), but since C++11, it becomes POD type (because it has the same access control for all non-static data members).


int main() {
    std::cout << "PublicBase: is_standard_layout=" << is_standard_layout<PublicBase>::value
              << ", is_trivial=" << is_trivial<PublicBase>::value
              << ", is_pod=" << is_pod<PublicBase>::value << std::endl;

    std::cout << "PrivateBase: is_standard_layout=" << is_standard_layout<PrivateBase>::value
              << ", is_trivial=" << is_trivial<PrivateBase>::value
              << ", is_pod=" << is_pod<PrivateBase>::value << std::endl;
}
// Output:
// PublicBase: is_standard_layout=1, is_trivial=1, is_pod=1
// PrivateBase: is_standard_layout=1, is_trivial=1, is_pod=1

Confusion on template copy assignment function

[First of First: Vs2019 on Windows10, only C++11 supported]

I've got confused on template copy assignment function like: enter image description here

I found the specilization version is not working, why it is not equal to copy assignment function? isn't that template function will be "extended" like macro?

Let's add a move constructor like this: enter image description here

I know that a userd-declared move constructor will set the implicit copy assignment function to delete. if the template copy assignment function is not a "REAL" copy assignment function, then why the compiler says:

error C2280: 'TestClass &TestClass::operator =(const TestClass &)': attempting to reference a deleted function
message : compiler has generated 'TestClass::operator =' here
message : 'TestClass &TestClass::operator =(const TestClass &)': function was implicitly deleted because 'TestClass' has a user-defined move constructor

So, How does compiler see on the template copy assignment function? Why it is omitted in the first case but trigger a compiler error in the second case?

Thanks in advance!

I expect the specilization version of template copy assignment function to be identical to copy assignment function.

The program is not entering the if condition [duplicate]

I have recently started learning C++ and wanted to try something just for fun. But I ran into a problem. Here is the code:

#include <iostream>

int num;

void enter_code(int passcode) {
  std::string secret_knowledge = "E=mc2";

  if (passcode == 0310) {
    
    std::cout << secret_knowledge << "\n";
    
  } else {
    
    std::cout << "Sorry, incorrect!\n";
    
  }
}

int main() {
  
  std::cout <<"Enter pass\n";
  std::cin >>num;

 if(num==0310)
 {
    enter_code(0310);
 }
 else{
    enter_code(num);
 }


}

Even if I enter the correct passcode, the output is "Sorry, incorrect!. Where am I going wrong?

samedi 24 juin 2023

Unable to Locate Multiple Definitions Linker Error [duplicate]

I am trying to understand what happens during the linking stage of the translation process in C++. Basically I was experimenting with header files and wanted to see if it's alright to define functions in header files as opposed to separating them in their respective cpp files. That said, I have World.h and its definitions written in the same file. The same goes for my Util.h header file.

The problem occurred when I was in the middle of separating function definitions into their own separate source files. But instead of just following basic protocol, I first want to understand why this is happening.

PS: I am fully aware that best practice would be to separate the definitions from the function declarations in another source file. I just wanted to experiment a bit.

Inside the Util.h file (The gcf function produces the multiple definitions error):

#pragma once

...

int gcf(int a, int b)
{
    if (a == 0) return b;
    return gcf(b % a, a);
}

World.h:

#pragma once

#include <SFML/Graphics.hpp>
#include "Paddle.h"
#include "Ball.h"
#include "Util.h"

class Paddle;
class Ball;

class World
{...};

Paddle.cpp:

#include "World.h"
#include "Paddle.h"

Paddle::Paddle(const sf::Vector2f& size, const Side& side, World& world)
: sf::RectangleShape(size), m_Side(side), m_World(&world) {}

...

Ball.cpp:

#include <cstdlib>
#include <cmath>

#include "World.h"
#include "Ball.h"

Ball::Ball(const sf::Vector2f& size, float speed, World& world)
: sf::RectangleShape(size), m_Speed(speed), m_World(&world)
{
    initializeVelocity();
}

...

As you can see, I included Util.h in World.h. Then, in Paddle.cpp and Ball.cpp, I included World.h in both of them because I have a circular dependency (World.h also refers to Paddle.h and Ball.h). I think it is also important to note that the Paddle.cpp and Ball.cpp files have their own corresponding header files with only the declarations. Only Util.h and World.h have function definitions with them in the same file (Also GameView.h but that header file is not relevant).

So is this why the error occurs? Because I was including World.h in two translation units or source files? If so, then I have firm reason to believe that I am misunderstanding the purpose of include guards or #pragma once. I thought these are enough to prevent linker errors but it turns out it can't prevent duplication in two source files. Can somebody explain to me how include guards actually work and why I'm getting the linker error? It would be very much appreciated.

Here is the full source code in my GitHub if you want to see the full context. It's a Pong game clone I'm trying to code using SFML.

And here's the linker error I get:

/usr/bin/ld: Main.o: in function `gcf(int, int)':
Main.cpp:(.text+0x0): multiple definition of `gcf(int, int)'; Ball.o:Ball.cpp:(.text+0x0): first defined here
/usr/bin/ld: Paddle.o: in function `gcf(int, int)':
Paddle.cpp:(.text+0x0): multiple definition of `gcf(int, int)'; Ball.o:Ball.cpp:(.text+0x0): first defined here
collect2: error: ld returned 1 exit status

vendredi 23 juin 2023

c hard 'std::bad_alloc' issue

Below is the MRE.

#include <iostream>
#include <string>
#include <cstdarg>

#define Level                2
#define Event_Client_Status  3

class Event
{
public:
   Event(const int ll, const int ty, const char* f, const int ln) :
      level(ll), type(ty), func(f), line(ln)
   {}
private:
   int level;
   int type;
   std::string func;
   int line;
};

class ClientStatusEvent : public Event
{
public:
   ClientStatusEvent(const int ty, const char* f, const int ln, va_list arguments) :
      Event(Level, ty, f, ln),
      client_name(va_arg(arguments, std::string))
   {}
private:
   std::string client_name;
};


void test_create_event(const int type, const char* func, const int line, ...)
{
   Event* event = nullptr;

   va_list arguments;
   va_start(arguments, line);
   event = new ClientStatusEvent(type, func, line, arguments);
   va_end(arguments);
}


int main()
{
   test_create_event(Event_Client_Status, "", 0, "client name");
}

The is the error when running it.

terminate called after throwing an instance of 'std::bad_alloc'
  what():  std::bad_alloc
Aborted (core dumped)

Replace nth regex match in C

I've found this topic which only explains how to replace the first regex match. What about some n'th match?

Say I have a string and a regex like these:

std::string str  = "fast cast dust crust must last rust";
std::regex  expr = " .(a|u)st";

How can I replace, say, the third match with some other sequence? std::regex_replace allows to replace either all matches or the first one. I'm also thinking about std::regex_iterator, but still can't figure out how to apply it in this task. What are the most convenient ways to solve the problem?

Why must I use this-> to call shared_from_this()? [duplicate]

I have some code in a multi platform project, that compiles fine with visual studio, but fails to compile with g++ and clang++, when I call shared_from_this(), instead of this->shared_from_this().

I was able to strip it down to this minimal code example:

#include <memory>

struct class1: public std::enable_shared_from_this<class1>
{
    template<typename T>
    struct class2: public std::enable_shared_from_this<class2<T>>
    {
        void func()
        {
            this->shared_from_this(); // this works
            shared_from_this(); // this gives an error ???
        }
    };
};

void foo()
{
    class1::class2<int>().func();
}

g++ gives this error:

$ g++ -c bug.cpp
bug.cpp: In instantiation of ‘void class1::class2<T>::func() [with T = int]’:
bug.cpp:18:28:   required from here
bug.cpp:11:41: error: cannot call member function ‘std::shared_ptr<_Tp> std::enable_shared_from_this<_Tp>::shared_from_this() [with _Tp = class1]’ without object
   11 |                         shared_from_this(); // this gives an error ???
      |                         ~~~~~~~~~~~~~~~~^~

clang++ gives this error:

$ clang++ -c bug2.cpp
bug.cpp:11:4: error: call to non-static member function without an object argument
                        shared_from_this(); // this gives an error ???
                        ^~~~~~~~~~~~~~~~
bug.cpp:18:24: note: in instantiation of member function 'class1::class2<int>::func' requested here
        class1::class2<int>().func();
                              ^

Both compiler agree in that I want to call a member function without an instance and yes, I have not explicitly specified this as the instance to use. But shouldn't I be able to call member functions on this instance without explicitly specifying this->?

I tried to further strip down the code by removing the outer class and got this code, that also does not compile, but gives a different error message:

#include <memory>

template<typename T>
struct class1: public std::enable_shared_from_this<class1<T>>
{
    void func()
    {
        this->shared_from_this(); // this works
        shared_from_this(); // this gives an error ???
    }
};

void foo()
{
    class1<int>().func();
}

g++ now gives this error:

$ g++ -c bug1.cpp
bug1.cpp: In member function ‘void class1<T>::func()’:
bug1.cpp:9:17: error: there are no arguments to ‘shared_from_this’ that depend on a template parameter, so a declaration of ‘shared_from_this’ must be available [-fpermissive]
    9 |                 shared_from_this(); // this gives an error ???
      |                 ^~~~~~~~~~~~~~~~
bug1.cpp:9:17: note: (if you use ‘-fpermissive’, G++ will accept your code, but allowing the use of an undeclared name is deprecated)

clang++ now gives this error:

+ clang++ -c bug1.cpp
bug1.cpp:9:3: error: use of undeclared identifier 'shared_from_this'
                shared_from_this(); // this gives an error ???

Is my code really buggy (and if yes, why?), or is this a common bug in g++ and clang++?

jeudi 22 juin 2023

FFmpeg avcodec C implementation producing distorted frames while converting YUV frame to jpg

I have a YUV frame that I need to convert to jpg. For the frames with resolution 1920x1080 or 2560x1080 or 2560x880 or 640x360, I'm easily able to encode and create a jpg using the following code. The frames with a resolution of 1512x982 with 12 bit per pixel I am getting a distorted image using the same code. Using the following ffmpeg command, I am able to get perfect looking jpg image from the same 1512x982 resolution YUV file:

fmpeg -y -s:v 1512x982 -pix_fmt yuv420p -i 0.yuv 0.jpg

Please help with the code part, as in what I may be missing here.

Distorted jpg

#include "ffmpeg-helper.h"

AVFrame * FFmpegHelper::allocPicture(enum AVPixelFormat pix_fmt, int width, int height)
{
    // Allocate a frame
    AVFrame * frame = av_frame_alloc();

    if (frame == NULL) {
        return NULL;
    }

    frame -> width = width;
    frame -> height = height;
    frame -> format = pix_fmt;
    int ret = av_frame_get_buffer(frame, 0);

    if (ret < 0) {
        return NULL;
    }
    ret = av_frame_make_writable(frame);
    if (ret < 0) {
        return NULL;
    }
    return frame;
}

void FFmpegHelper::frameConversion(char * y, char * u, char * v,
    int srcWidth, int srcHeight, string filePath)
{
    avcodec_register_all();
    AVFrame * src = allocPicture(AVPixelFormat::AV_PIX_FMT_YUV420P, srcWidth, srcHeight);
    src -> data[0] = (uint8_t * ) y;
    src -> data[1] = (uint8_t * ) u;
    src -> data[2] = (uint8_t * ) v;
    src -> pts = 1;

    auto encoderContext = getEncoderContext(AV_CODEC_ID_MJPEG, srcWidth, srcHeight);
    if (encoderContext == NULL) return;

    FILE * frameFile = fopen(filePath.c_str(), "ab+");

    auto pkt = av_packet_alloc();
    encode(encoderContext, src, pkt, frameFile);
    encode(encoderContext, NULL, pkt, frameFile);

    // memory cleanup
    avcodec_free_context( & encoderContext);
    av_packet_unref(pkt);
    av_frame_free( & src);
    fclose(frameFile);
}

void FFmpegHelper::encode(AVCodecContext * enc_ctx, AVFrame * frame, AVPacket * pkt, FILE * outfile)
{
    /* send the frame to the encoder */
    if (frame == NULL) {
        return;
    }
    int ret = avcodec_send_frame(enc_ctx, frame);
    if (ret < 0) {
        return;
    }
    ret = avcodec_receive_packet(enc_ctx, pkt);
    if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) return;
    if (ret < 0) return;
    fwrite(pkt -> data, pkt -> size, 1, outfile);

}

AVCodecContext * FFmpegHelper::getEncoderContext(AVCodecID extension, int width, int height)
{
    auto codec = avcodec_find_encoder(extension);
    if (!codec) {
        return NULL;
    }
    auto encoderContext = avcodec_alloc_context3(codec);
    encoderContext -> width = width;
    encoderContext -> height = height;
    encoderContext -> pix_fmt = AVPixelFormat::AV_PIX_FMT_YUVJ420P;
    AVRational frameRate = {
        1,
        1
    };
    encoderContext -> time_base = frameRate;
    if (avcodec_open2(encoderContext, codec, NULL) < 0) {
        return;
    }

    return encoderContext;
}

The code starts from the function 'frameConversion' where I am providing data for Y, U, and V along with frame dimensions and file path to write.

dictionary with pair/index?

Which structure is more suited in C++ (11) for store object accessing to them using a pair index?

Tried somethings like this:

typedef std::map<std::pair<int, int>, MyObject> MyDictionaryPairIndexes;

using:

std::pair<int, int>

as pair index, but

  1. not sure how to access to it later using a pair index (at() what?)
  2. if that's the correct way

Any example?

mercredi 21 juin 2023

C Different Memory Order meaning in simple terms with example

I was trying to grasp different memory_order meanings in a simple term and understand it in details. I have read through https://en.cppreference.com/w/cpp/atomic/memory_order and to some extent understand the usage of some of these for synchronization. I do understand that memory_order_seq_cst do guarantee strictness around load and store, which would mean no surprises but at an overhead and there can be cases when even mutex would be faster than these depending on scenario. I wanted to understand the meaning of each of these memory_order and their significance in simple terms memory_order_relaxed, memory_order_consume, memory_order_acquire, memory_order_release, memory_order_acq_rel, memory_order_seq_cst. E.g in case of memory_order_relaxed compiler can move statements below and above that atomic variable with memory_order_relaxed. So below could result into an output of 37 0

 Global
 atomic<int> x, y;

 Thread 1                            Thread 2
 x.store(17,memory_order_relaxed);   cout << y.load(memory_order_relaxed) << " ";
 y.store(37,memory_order_relaxed);   cout << x.load(memory_order_relaxed) << endl;`

But the same example with memory order modified to memory_order_release and memory_order_acquire makes sure that output cannot be 37 0 ever.

 Global
 atomic<int> x, y;

 Thread 1                            Thread 2
 x.store(17,memory_order_release);   cout << y.load(memory_order_acquire) << " ";
 y.store(37,memory_order_release);   cout << x.load(memory_order_acquire) << endl;

I want to understand these memory_order variables in a better way so that I am more comfortable using them instead of using sequence consistency most of the time which would degrade the performance.

Note that i did looked at C++11 introduced a standardized memory model. What does it mean? And how is it going to affect C++ programming? SO answer.

mardi 20 juin 2023

c cannot use mutex along with vector

I have trouble compiling the following code.

#include <vector>
#include <mutex>


class A
{
public:
  A(){}
private:
  std::mutex a_mutex;
};


int main()
{
   std::vector<A> v;
   A a;
   v.push_back(a);
   return 0;
}

This is the error.

$ g++ test__use_of_deleted_function.cpp
In file included from /usr/include/c++/8/x86_64-redhat-linux/bits/c++allocator.h:33,
                 from /usr/include/c++/8/bits/allocator.h:46,
                 from /usr/include/c++/8/string:41,
                 from test__use_of_delete_function.cpp:1:
/usr/include/c++/8/ext/new_allocator.h: In instantiation of ‘void __gnu_cxx::new_allocator<_Tp>::construct(_Up*, _Args&& ...) [with _Up = A; _Args = {const A&}; _Tp = A]’:
/usr/include/c++/8/bits/alloc_traits.h:475:4:   required from ‘static void std::allocator_traits<std::allocator<_CharT> >::construct(std::allocator_traits<std::allocator<_CharT> >::allocator_type&, _Up*, _Args&& ...) [with _Up = A; _Args = {const A&}; _Tp = A; std::allocator_traits<std::allocator<_CharT> >::allocator_type = std::allocator<A>]’
/usr/include/c++/8/bits/stl_vector.h:1079:30:   required from ‘void std::vector<_Tp, _Alloc>::push_back(const value_type&) [with _Tp = A; _Alloc = std::allocator<A>; std::vector<_Tp, _Alloc>::value_type = A]’
test__use_of_delete_function.cpp:19:17:   required from here
/usr/include/c++/8/ext/new_allocator.h:136:4: error: use of deleted function ‘A::A(const A&)’
  { ::new((void *)__p) _Up(std::forward<_Args>(__args)...); }
    ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
test__use_of_delete_function.cpp:6:7: note: ‘A::A(const A&)’ is implicitly deleted because the default definition would be ill-formed:
 class A
       ^
test__use_of_delete_function.cpp:6:7: error: use of deleted function ‘std::mutex::mutex(const std::mutex&)’
In file included from /usr/include/c++/8/mutex:43,
                 from test__use_of_delete_function.cpp:3:
/usr/include/c++/8/bits/std_mutex.h:97:5: note: declared here
     mutex(const mutex&) = delete;
     ^~~~~
In file included from /usr/include/c++/8/vector:62,
                 from test__use_of_delete_function.cpp:2:
/usr/include/c++/8/bits/stl_construct.h: In instantiation of ‘void std::_Construct(_T1*, _Args&& ...) [with _T1 = A; _Args = {A}]’:
/usr/include/c++/8/bits/stl_uninitialized.h:83:18:   required from ‘static _ForwardIterator std::__uninitialized_copy<_TrivialValueTypes>::__uninit_copy(_InputIterator, _InputIterator, _ForwardIterator) [with _InputIterator = std::move_iterator<A*>; _ForwardIterator = A*; bool _TrivialValueTypes = false]’
/usr/include/c++/8/bits/stl_uninitialized.h:134:15:   required from ‘_ForwardIterator std::uninitialized_copy(_InputIterator, _InputIterator, _ForwardIterator) [with _InputIterator = std::move_iterator<A*>; _ForwardIterator = A*]’
/usr/include/c++/8/bits/stl_uninitialized.h:289:37:   required from ‘_ForwardIterator std::__uninitialized_copy_a(_InputIterator, _InputIterator, _ForwardIterator, std::allocator<_Tp>&) [with _InputIterator = std::move_iterator<A*>; _ForwardIterator = A*; _Tp = A]’
/usr/include/c++/8/bits/stl_uninitialized.h:311:2:   required from ‘_ForwardIterator std::__uninitialized_move_if_noexcept_a(_InputIterator, _InputIterator, _ForwardIterator, _Allocator&) [with _InputIterator = A*; _ForwardIterator = A*; _Allocator = std::allocator<A>]’
/usr/include/c++/8/bits/vector.tcc:447:6:   required from ‘void std::vector<_Tp, _Alloc>::_M_realloc_insert(std::vector<_Tp, _Alloc>::iterator, _Args&& ...) [with _Args = {const A&}; _Tp = A; _Alloc = std::allocator<A>; std::vector<_Tp, _Alloc>::iterator = __gnu_cxx::__normal_iterator<A*, std::vector<A> >; typename std::_Vector_base<_Tp, _Alloc>::pointer = A*]’
/usr/include/c++/8/bits/stl_vector.h:1085:4:   required from ‘void std::vector<_Tp, _Alloc>::push_back(const value_type&) [with _Tp = A; _Alloc = std::allocator<A>; std::vector<_Tp, _Alloc>::value_type = A]’
test__use_of_delete_function.cpp:19:17:   required from here
/usr/include/c++/8/bits/stl_construct.h:75:7: error: use of deleted function ‘A::A(A&&)’
     { ::new(static_cast<void*>(__p)) _T1(std::forward<_Args>(__args)...); }
       ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
test__use_of_delete_function.cpp:6:7: note: ‘A::A(A&&)’ is implicitly deleted because the default definition would be ill-formed:
 class A
       ^
test__use_of_delete_function.cpp:6:7: error: use of deleted function ‘std::mutex::mutex(const std::mutex&)’
In file included from /usr/include/c++/8/mutex:43,
                 from test__use_of_delete_function.cpp:3:
/usr/include/c++/8/bits/std_mutex.h:97:5: note: declared here
     mutex(const mutex&) = delete;
     ^~~~~

C run time check failure #2 stack around the variable LocalStruct was corrupted

We have a code that runs a dll but right at the end of the function, at the last curly brace, I get this error = run time check failure #2 stack around the variable was corrupted. This is not caused by my vector being out of bounds.

My code is -

vector<LocalStruct> arr(1000);
for(auto x : ArrayOfLocalStructs)
{
arr.push_back(x);
}
return arr;

Thus, I am not accessing an out of bounds vector since vector can obviously double its size when it gets filled. All answers I have found online have an out of bounds array index error but for my code everything was working yesterday. Is it may be because of some corrupted system files since our application is a MFC application which also accesses system files.

The above code is in a DLL file in my workplace, but the code looks like the small snippet I added. When running this snippet in visual studio alone, it doesn't throw any error, but only does on the DLL file at my workplace. Is there any way to debug this? Since in debugger it just fails at the last curly brace of the function?

lundi 19 juin 2023

thread_local strange inlining

So for the following code, I see a strange inlining/optimisation artefact.

I'm curious to know if they are "necessary" in some hypothetical scenario I'm not appreciating?

Godbolt: https://godbolt.org/z/M8PW1obE7

#include <cstdint>
#include <stdio.h>
struct ThreadStateLogger
{
    static thread_local struct Instance
    {
        char TLS_byteLoc[3]    {' ', 0, 0};
        uint8_t TLS_numBytes    {1};
        // 4 wasted bytes here...
        char* TLS_byteLocPtr {TLS_byteLoc};

        void Log(char v)
        {
            TLS_byteLocPtr[0] = v;
        }

        void Log(char v1, char v2)
        {
            TLS_byteLocPtr[0] = v1;
            if (TLS_numBytes>1)
                TLS_byteLocPtr[1] = v2;
        }
    } instance;

    static void Log(char v1, char v2)
    {
        instance.Log(v1, v2);
    }

    // static void Log(char v1, char v2)
    // {
    //     instance.TLS_byteLocPtr[0] = v1;
    //     if (instance.TLS_numBytes>1)
    //         instance.TLS_byteLocPtr[1] = v2;
    // }

};
extern ThreadStateLogger theThreadStateLogger;
int main()
{
    ThreadStateLogger::Log('a', 'b');
    // printf("Hello world");
    ThreadStateLogger::Log('c', 'd');
    return 0;
}

The whole primary implementation gets inlined with -O3, which is what I want :-)

So it appears that the first Log() call correctly checks if this TLS needs allocating, and then gets the converted address using __tls_get_addr@PLT, which is all good.

The second Log() call also apparently checks if the object needs initialising, but then uses the cached addresses from the first call (rbx)! So if it did initialise, that could be wrong?

Below is the output from clang16 on godbolt, which is comparable to gcc - the same reinitialization test and cached address, but it does somewhat better than my current clang10 with -fPIC. https://godbolt.org/z/M8PW1obE7

main:                                   # @main
        push    rbx
        cmp     qword ptr [rip + _ZTHN17ThreadStateLogger8instanceE@GOTPCREL], 0
        je      .LBB0_2
        call    TLS init function for ThreadStateLogger::instance@PLT
.LBB0_2:
        data16
        lea     rdi, [rip + ThreadStateLogger::instance@TLSGD]
        data16
        data16
        rex64
        call    __tls_get_addr@PLT
        mov     rbx, rax
        mov     rax, qword ptr [rax + 8]
        mov     byte ptr [rax], 97
        cmp     byte ptr [rbx + 3], 2
        jae     .LBB0_3
        cmp     qword ptr [rip + _ZTHN17ThreadStateLogger8instanceE@GOTPCREL], 0
        jne     .LBB0_5
.LBB0_6:
        mov     rax, qword ptr [rbx + 8]
        mov     byte ptr [rax], 99
        cmp     byte ptr [rbx + 3], 2
        jae     .LBB0_7
.LBB0_8:
        xor     eax, eax
        pop     rbx
        ret
.LBB0_3:
        mov     rax, qword ptr [rbx + 8]
        mov     byte ptr [rax + 1], 98
        cmp     qword ptr [rip + _ZTHN17ThreadStateLogger8instanceE@GOTPCREL], 0
        je      .LBB0_6
.LBB0_5:
        call    TLS init function for ThreadStateLogger::instance@PLT
        mov     rax, qword ptr [rbx + 8]
        mov     byte ptr [rax], 99
        cmp     byte ptr [rbx + 3], 2
        jb      .LBB0_8
.LBB0_7:
        mov     rax, qword ptr [rbx + 8]
        mov     byte ptr [rax + 1], 100
        xor     eax, eax
        pop     rbx
        ret

edits REmoved a printf - MORE init checks have been added, but __tls_get_addr is still cached in rbx

  • I will have another "play" to understand what the codepaths are generating now. I may have to introduce some volatiles.

tldr

So reminder of the question: Why is the init check/call repeated? If that is necessary, then why does the address not need to be regenerated? Or is this just an optimisation nobody has thought of doing? Is there any way to get a better optimisation by juggling the code pattern? I have had a few goes to get to here, as you can see.

Single producer multiple consumers C

I am trying to implement a program that consists of a producer thread adding objects to a std::vector and multiple consumer threads removing objects from the same vector until it's empty. I am using a condition_variable to let the consumers know that new objects have been produced. Problem is that in last iteration (n items left in storage where n is number of consumer threads), consumer threads get stuck waiting on a conditional variable, even though that condition should not be met (storage is not empty -> at least that's what I figured with some debug logs).

#include <chrono>
#include <condition_variable>
#include <functional>
#include <iostream>
#include <mutex>
#include <thread>
#include <vector>

#define CONSUMER_COUNT 4
#define STORAGE_SIZE CONSUMER_COUNT * 10000

class Foo {
private:
  int _id;

public:
  Foo(int id) : _id(id) {}
  int getId() const { return _id; }
};

std::vector<Foo> storage;
std::mutex storageMutex;
std::condition_variable storageCV;

void Producer(int limit) {
  for (int i = 0; i < limit; ++i) {
    std::lock_guard<std::mutex> lg{storageMutex};
    storage.emplace_back(Foo(i));
    storageCV.notify_one();
  }
  storageCV.notify_all();
}

void Consumer(int id) {
  while (true) {
    std::unique_lock<std::mutex> ul{storageMutex};
    storageCV.wait(ul, []() { return !storage.empty(); });
    if (storage.empty())
      return;
    storage.pop_back();
  }
}

int main(int argc, char *argv[]) {
  std::vector<std::thread> consumers;
  consumers.reserve(CONSUMER_COUNT);

  auto producer = std::thread(Producer, STORAGE_SIZE);

  for (int i = 0; i < CONSUMER_COUNT; ++i) {
    consumers.emplace_back(std::thread(Consumer, i));
  }

  producer.join();
  for (auto &consumer : consumers)
    consumer.join();

  storageCV.notify_all();

  std::cout << "[MAIN] Done!" << std::endl;
  std::cout << "Storage is left with " << storage.size() << " items!"
            << std::endl;

  return 0;
}

I have tried adding a simple boolean flag that producer will toggle once it's done with adding all of the items, but then I am not sure (logically) how should I set the condition in consumer threads. Simply adding that check on top of current one is not enough because then a thread might stop running even though there are still some items in the storage.

samedi 17 juin 2023

"error while loading shared libraries: libstdc.so.6" on a restricted CentOS machine when running a cross-compiled GCC

I have a restricted CentOS machine without GCC, make, package manager, and root access. I want to compile some software on this machine. Therefore, I decided to cross-compile a GCC on my personal computer. First, I compiled binutils-2.37 followed by gcc-10.3.0. The cross-compiling process was successful, and I transferred the resulting binaries to the restricted CentOS machine.

However, when I tried to run the GCC binary on the CentOS machine, I got this error: error while loading shared libraries: libstdc++.so.6: cannot open shared object file: No such file or directory.

Here is the script i use to cross-compile my gcc.

...
# Step 3: Configure and compile Binutils
echo "Configuring and compiling Binutils..." | tee -a ${log_file}
cd binutils-${binutils_version}
mkdir -p ${output_dir}
./configure --prefix=${output_dir} --target=${your_target} &>> ${log_file}
make &>> ${log_file}
make install &>> ${log_file}
cd ..

# Step 4: Configure and compile GCC
echo "Configuring and compiling GCC..." | tee -a ${log_file}
cd gcc-${gcc_version}
export PATH=${output_dir}/bin:${PATH}
./contrib/download_prerequisites
./configure --prefix=${output_dir} --target=${your_target} --enable-languages=c,c++ --disable-multilib --disable-shared --enable-static
make all-gcc 
make install-gcc
...

What should I do to overcome this issue?

vendredi 16 juin 2023

how to avoid implicit conversion of arguments leading to infinite recursion?

I have a formatting method that I adapted from this example.

I have reduced it to just function calls and a print

It works when the formatting string (first argument) is a const char *

#include <stdio.h>
#include <string>

// base
std::string format(const char *s)
{
    printf("** %s\n",s);
    return "";
}
// recursive, should parse each argument and print the formatted string
template<typename T, typename... Args>
std::string format(const char *s, T value, Args... args)
{
    printf("** %s\n",s);  // dummy
    return "";
}

int main()
{
   format("foo");   
   printf("yay!\n");
}

now I'd like to pass a std::string to format, I have to do:

std::string s = "foo";
format(s.c_str());

I'd like to do

format(s);

So I have added this

// recursive
template<typename... Args>
std::string format(const std::string &s,Args... args)
{
  return format(s.c_str(), args...);
}

But when I pass the string directly as std::string it crashes. Debugging shows an infinite recursion. Difficult to debug templates with std::string constructions, but my guess is that

return format(s.c_str(), args...);

calls itself, because const char * implicitly converts as a std::string.

Here's the full non-working example:

#include <stdio.h>
#include <string>

// recursive
template<typename... Args>
std::string format(const std::string &s,Args... args)
{
  return format(s.c_str(), args...);
}


// base
std::string format(const char *s)
{
    printf("** %s\n",s);
    return "";
}
// recursive, should parse each argument and print the formatted string
template<typename T, typename... Args>
std::string format(const char *s, T value, Args... args)
{
    printf("** %s\n",s);  // dummy
    return "";
}

int main()
{
   std::string s = "foo";
   format(s);   
   printf("yay!\n");  // crashes before that
}

I could ditch const char * version altogether and go full std::string but I would like to avoid to build a string when a string literal is passed.

So how to keep the ability to pass either const char * directly or std::string as first argument ?

jeudi 15 juin 2023

Multilevel Inheritance project issue

I'm working on a multilevel inheritance project involving a deck of cards. RedCard and BlackCard have to inherit from Card. Heart and diamond from redcard. Spade and Club from blackcard. Right now im hung up on the blackcard and redcard, with my current code in the blackcard.cpp I can get the value(0 for unknown, 2-10 for numbered cards, 11-14 for face/aces) to output however I cannot get the color(red or black) to display after the value.

blackcard.cpp

#include "blackcard.h"

// parameterized constructor to create a black card of value v
BlackCard::BlackCard(int v):Card(v) // calls card class constructor 
{
    SetColor("black"); // sets the color of the card to "black"
}

string BlackCard::Description() const
{
    // Card::Description() returns the description from base class and appends the color information to it
    return Card::Description() + ", Color =" + Card::GetColor();
}
// end of blackcard.cpp

I will also attach the card.h file and card.cpp file

card.cpp

//
// card.cpp -- CPE 212-01, Fall 2010 -- Project02 -- Classes
//
// Add the missing statements to complete each method below
// and SUBMIT this file for grading !!!
//

#include <iostream>
#include <cstdlib>
#include "card.h"

Card::Card()
// Default Constructor: Initializes value to 0, color to "unknown", and suit to 'U'
{
  value = 0;
  color = "unknown";
  suit = 'U';
} 


Card::Card(int v)
// Parameterized Constructor: Initializes value to v, color to "unknown", and suit to 'U'
{
  value = v;
  color = "unknown";
  suit = 'U';
}  


int Card::GetValue() const
// Returns variable value
{
  return value;
}


string Card::GetColor() const
// Returns variable color
{
  return color;
}


char Card::GetSuit() const
// Returns variable suit
{
  return suit;
}


void Card::SetValue(int v)
// Sets value to v
{
  value = v;
}


void Card::SetColor(string c)
// Sets color to c
{
  color = c;
}


void Card::SetSuit(char s)
// Sets suit to s
{
  suit = s;
}



string Card::Description() const   
// Outputs card characteristics - value as a string
// DO NOT MODIFY THIS METHOD !!!!
{
  string d = "Value = ";    // temporary variable used to accumulate result

  switch (value)            // Append card value to variable's value
  {
    case 2:   d = d + "2";    break;      // Number cards
    case 3:   d = d + "3";    break;
    case 4:   d = d + "4";    break;
    case 5:   d = d + "5";    break;
    case 6:   d = d + "6";    break;
    case 7:   d = d + "7";    break;
    case 8:   d = d + "8";    break;
    case 9:   d = d + "9";    break;
    case 10:  d = d + "10";   break;
    
    case 11:  d = d + "J";    break;      // Face cards
    case 12:  d = d + "Q";    break;
    case 13:  d = d + "K";    break;
    case 14:  d = d + "A";    break;

    default:  d = d + "?";    break;      // Unknown card
  }

  return d;                 // Return string describing card value
}


card.h

//
// card.h -- CPE 212-01, Fall 2010 -- Project02 -- Classes
//
// Add the missing statements to complete the class declaration below
// and SUBMIT this file for grading !!!
//

#include <string>
using namespace std;

#ifndef CARD_H
#define CARD_H

class Card                      // Class modeling Card ADT
{
 private:
  int value;                    // Card value: 2-10 for number cards, 11-14 for JQKA; 0 for unknown
  string color;                 // Card color: "red", "black", or "unknown"
  char suit;                    // Card suit: 'H' for hearts, 'D' for diamonds, 'C' for clubs, 'S' for spades or 'U' for unknown

 public:
  //******** Add Constructor Prototypes Below  *********//
    Card();      // Default constructor prototype: creates card with value v, color unknown, and suit U
    
    Card(int v);        // Parameterized constructor prototype: creates card with value v, color unknown, and suit U
    
    
  //******** Add Transformer Prototypes Below *********//
    void SetValue(int v);      // SetValue prototype: Sets card value equal to v
    
    void SetColor(string c);     // SetColor prototype: Sets color value equal to c

    void SetSuit(char s);      // SetSuit prototype:  Sets suit value equal to s

    
  //******** Add Observer Prototypes Below *********//
    int GetValue() const;       // GetValue prototype: Returns current value of value
    
    string GetColor() const;      // GetColor prototype: Returns current value of color
    
    char GetSuit() const;     // GetSuit prototype:  Returns current value of suit

    string Description() const;      // Description prototype: Polymorphic Function!!!
                                // Outputs card characteristics - value as a string (see sample output from p01input1.txt)
};


#endif

I'm not really sure what to try

mercredi 14 juin 2023

how to resolve c build error: 'declaration of anonymous class must be a definition' [closed]

Getting the following error when running make using c++11 on a mac m1:

./Continuous.h:623:1: error: declaration of anonymous class must be a definition
class LTI_ODE  
^

the code snippet is:

class LTI_ODE
{
protected:
    iMatrix A;
    iMatrix B;
    iMatrix C;
    iMatrix constant;

    bMatrix connectivity;

    std::vector<Interval> dist_range;

public:
    LTI_ODE(iMatrix & A_input, iMatrix & B_input, iMatrix & C_input, iMatrix & constant_input, const std::vector<Interval> & dist_range_input);
    ~LTI_ODE();

    void one_step_trans(iMatrix & Phi, iMatrix & Psi, iMatrix & trans_constant, Zonotope & dist, const double step, const int order);
};

I don't think it's an anonymous class, hence, I don't know how to fix it?

mardi 13 juin 2023

Why OpenMp cannot be found when libomp has already been installed on Mac?

Following error info occurs when starting to build a c++ project on my Mac.

CMake Warning at cmake/check_requirements.cmake:64 (message):
  OpenMP not found
Call Stack (most recent call first):
  CMakeLists.txt:13 (include)


CMake Error at cmake/check_requirements.cmake:103 (message):
  can not find appropriate macosx SDK, find in
  /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk;/Library/Developer/CommandLineTools/SDKs/MacOSX12.3.sdk;/Library/Developer/CommandLineTools/SDKs/MacOSX12.sdk;/Library/Developer/CommandLineTools/SDKs/MacOSX13.1.sdk;/Library/Developer/CommandLineTools/SDKs/MacOSX13.3.sdk;/Library/Developer/CommandLineTools/SDKs/MacOSX13.sdk,
  you may set SDKROOT manually
Call Stack (most recent call first):
  CMakeLists.txt:13 (include)

And I had already installed libomp and other tools.
Details about env is:

  • Mac is mbp 2018 with intel core.
  • cmake: version 3.26.4

I had searched a lot of answers, which all seems useless to my problem.
Thank you.

Capturing a `thread_local` in a lambda

Capturing a thread_local in a lambda:

#include <iostream>
#include <thread>
#include <string>

struct Person
{
    std::string name;
};

int main()
{
    thread_local Person user{"mike"};
    Person& referenceToUser = user;

    // Works fine
    std::thread([&]() {std::cout << "Hello " << referenceToUser.name << std::endl;}).join();

    // Doesn't work
    std::thread([&]() {std::cout << "Hello " << user.name << std::endl;}).join();

    // Works fine
    std::thread([&user=user]() {std::cout << "Hello " << user.name << std::endl;}).join();
}

https://godbolt.org/z/zeocG5ohb

It seems like if I use the original name of a thread_local then its value on the thread which executes the lambda is the thread_local version of the thread which is running the lambda. But as soon as I take a reference or pointer to the thread local it turns into (a pointer to) the originating threads instance.

What are the rules here. Can I rely on this analysis?

What are the new ways to pass functions as template arguments in C++11?

In the question Function passed as template argument, it was asked and explained that there are two traditional ways of passing a function as a template argument in C++, they're:

  1. Declaring the function as a "functor" (e.g. an object with an overridden () operator). But it requires modifying the target function first.
  2. Using function pointer as the parameter, and taking the address of the function with the & operator to use the template. But this can possibly inhibit compiler optimization, especially inlining, since the compiler may be unable to figure out the target of the naked pointer.

I have read and conceptually understood both methods. However, in a comment by user pfalcon under the answer, it was claimed that:

Fast forward to few years later, situation with using functions as template arguments much improved in C++11. You no longer bound to use Javaisms like functor classes, and can use for example static inline functions as template arguments directly. Still far cry comparing to Lisp macros of 1970s, but C++11 definitely has good progress over the years.

But no expatiation or example is given. What are the supposedly "much improved" ways of doing that in C++11 that pfalcon was referring to? I tried to search "function as template argument C++11" but I didn't see any usable result.

lundi 12 juin 2023

How to write to PCM and Wav Files [closed]

Can someone explain to me how do you write to Wav files and PCM files ?? What do I need to know? Do I need to know the size and etc?

Sorry if its a stupid question, I know how to write to text files but I have just been stucked with Wav and Pcm right now for a couple of days and I just don't get it and feel kinda dumb.

In C++, is it possible to compile a static library with an extern variable that will be declared by the code that calls the library?

I am trying to adapt someone else's C++ code. It is currently structured as a series of libraries that are statically linked, and eventually called by the main program. Each one of these libraries is compiled using a Makefile. I have hit a problem that I do not understand. Some variables in one of these libraries will only be given values by the main program. These are declared using extern int externValue. However, when I try to compile this part of the code into the library, I get an error saying externValue is an undefined symbol.

The code looks something like this. First the Makefile:

CFLAGS = -g -Wall -O -I/some/file/path/include/ -fpic
LFLAGS = -shared
SRC = source.cc
OBJ = source.o

all: libsource.so

libsource.so: $(OBJ)
    g++ $(CFLAGS) $(LFLAGS) -o libsource.so $(OBJ)

source.o: source.cc
    g++ $(CFLAGS) -c source.cc

the source file source.cc (here passing it for output is just a random action to access the variable):

#include <iostream>
#include "source.h"

extern int externValue;

void testFunc()
{
  std::cout << externValue << std::endl;
}

and the header source.h:

#ifndef __source_h__
#define __source_h__

void testFunc();

#endif

When I run make, I get the following error:

g++ -g -Wall -O -I/some/file/path/include/ -fpic -c source.cc
g++ -g -Wall -O -I/some/file/path/include/ -fpic -shared -o libsource.so source.o
Undefined symbols for architecture x86_64:
  "_externValue", referenced from:
      testFunc() in source.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make: *** [libsource.so] Error 1

Am I simply misunderstanding how extern works? Can I compile the libary without a specific value for externValue?

This part of the code will compile if I shift from extern int externValue to int externValue. However, I want to understand how the code was meant to work in the first place, as the source code I was given has produced results in the past. The same approach appears elsewhere in the code. Why deos the code need these variables to be fully declared, rather than just defined, as it is not yet being run.

dimanche 11 juin 2023

Auto deduction of non-type template char parameters from a string in c++11

Let's say we have the following structure defined

template <char T, char S>
struct chars_trait {}

Moreover, we have a bunch of two-char strings, for instance

const std::string ab = "ab";
const std::string cd = "cd";
const std::string ef = "ef";

My goal is to create chars_trait object for each of those strings, so

ab -> chars_trait<'a','b'>{}
cd -> chars_trait<'c','d'>{}
ef -> chars_trait<'e','f'>{}

and use them, for instance, like this

std::for_each(vecOfStrs.begin(), vecOfStrs.end(),
              [&](const std::string& str){doSthWithCharsTrait(getCharTrait(str));});

I have tried to employ a map but got stuck with two problems - first that this approach is possible from c++14, and second, much more significant - it does not work. So my question is - can I somehow improve my code? Or there is no chance of making it as I proposed?

All code here

#include <iostream>
#include <string>
#include <map>

const std::string ab = "ab";
const std::string cd = "cd";
const std::string ef = "ef";

template <char T, char S>
struct chars_trait {};

template <char T, char S>
std::map<std::string, chars_trait<T, S>> MAPPER
{
    {ab, chars_trait<'a', 'b'>{}},
    {cd, chars_trait<'c', 'd'>{}},
    {ef, chars_trait<'e', 'f'>{}}  
};

template <char T, char S>
void print(const chars_trait<T, S>&)
{
    std::cout << T << S << std::endl;
}

void print(const std::string& str)
{
    print(MAPPER.at(str));
}


int main()
{
    print(ab);
    return 0;
}

samedi 10 juin 2023

Map Enum Values with Template Type

NOTE: I've seen a lot of answers on this topic, but the problem is that I don't quite understand how metaprogramming works, although I've used it in some way. Therefore, I would like to get an answer for my case. Don't judge strictly. :)

Main Issue:

First i've have simple enum where i store the ComponentTypes like this:

typedef enum ComponentType {
   ComponentType_ID,
   ComponentType_Editor,
   ComponentType_Tag,
   ComponentType_Transform
} ComponentType;

Second i've have struct's for each of this component type:

struct Component  {
};

struct IDComponent : public Component {
};

struct EditorComponent : public Component {
};

struct TagComponent : public Component {
};

struct TransformComponent : public Component {
};

I can do conversion only from template type to enum types like this:

template<typename T>
constexpr ComponentType ComponentTypeFromTemplate() {
if (std::is_base_of_v<Component, T>) {
    if      (std::is_same_v<T, IDComponent>)               return ComponentType_ID;
    else if (std::is_same_v<T, EditorComponent>)           return ComponentType_Editor;
    else if (std::is_same_v<T, TagComponent>)              return ComponentType_Tag;
    else if (std::is_same_v<T, TransformComponent>)        return ComponentType_Transform;
}

But how i can convert enum ComponentType types to template type specific?

or

How i can map this types with enum types using metaprogramming and templates, so i can return the template type using function and trailing return types?

And use something like this:


constexpr ComponentType type = ComponentType_ID;
using T = ComponentTypeToTemplate(type); // do some magic to get T

if constexpr(std::is_same<T, IDComponent>)
   std::cout << "IDComponent is currect" << std::endl;

constexpr ComponentType type2 = ComponentType_Transform;
using T2 = ComponentTypeToTemplate(type2); // do some magic to get T

if constexpr(std::is_same<T2, TransformComponent>)
   std::cout << "TransformComponent is currect" << std::endl;

How to build a student Management System in c++? [closed]

Student Management System:

Manage student records, including their personal details, courses enrolled, and grades.

Allow for student registration and enrollment in different courses.

Generate reports such as student lists, course schedules, and academic performance.

Manage student records, including their personal details, courses enrolled, and grades.

Allow for student registration and enrollment in different courses.

Generate reports such as student lists, course schedules, and academic performance.

push_back() not working on more than one vector in one function...why?

I'm new to coding (and to Stack Overflow), learning about the basics of C++ right now. I want to write a simple program that: A) collects days (strings) of a week B) collects numbers (ints) that represent orders delivered during the week, and C) prints out the day - order pairs.

I've been trying to use push_back() to do this, and it seems like whatever I do, push_back() works only on the first vector. Does anyone know why this is? Am I missing something fundamental about push_back()? Any help is greatly appreciated!^-^

The result of this code right now is a runtime error coming from the last part where I try to print the pairs. When you remove the orders vector from cout, the code works... This is why I think that the problem is that somehow push_back() doesn't work on the orders vector, and therefore its non-existent elements cannot be printed. What do you think?


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

int main()
{

// collecting workdays:
// example input: Monday Tuesday Friday
cout << "Please enter the days you have worked on during this week:\n";

vector <string> days;

for (string s; cin >> s; ) 
    days.push_back(s);

// collecting orders delivered:
// example input: 11 12 10
cout << "Please enter the number of orders you delivered each day this week:\n";

vector <int> orders;

for (int x; cin >> x; )
    orders.push_back(x);

// printing day - order pairs
/* desired output based on the example input & output:
Monday = 11 orders
Tuesday = 12 orders
Friday = 10 orders */
for (int i = 0; i < days.size(); ++i)
    cout << days[i] << " = " << orders[i] << "orders\n";

return 0;
}

vendredi 9 juin 2023

boost::spirit and lambda functions

My boost spirit code using lambdas for production of AST elements, does only compile if I use lambdas without capture and WITH a leading +.

does not compile:

_val = boost::phoenix::bind(
    [&](const double _d)
    {    return m_sFactory->value(_d);
    },
    qi::_1
)

compiles fine:

_val = boost::phoenix::bind(
    +[](const factory&_r, const double _d)
    {    return _r.value(_d);
    },
    *m_sFactory,
    qi::_1
)

Why is that?

Is the move constructor only come in handy if my class has a member that is a raw pointer?

I am currently studying the move constructor and the copy constructor. Based on my current understanding, these constructors are used to initialize an object of class X by providing another object of the same class type X. However, there is a distinction between the two: the copy constructor takes a non-temporary object as input, while the move constructor takes a temporary object.

Both the copy and move constructors are particularly useful when a class has a member that is a raw pointer, which may point to memory allocated on the heap.

so what if my class doesn`t have a pointer member just a collection of members of integers and strings and array of doubles for example , how would the copy and move constructor be so important and remove the overhead provided by the default argument constructors? and how would the implementation of the two constructors be done in this case? I am taking about the C++ language

I haven`t tried this case yet. but I tried it with the case of my class has a raw pointer

jeudi 8 juin 2023

C++: Why does ncurses getch() appear to be blocking output, and how do I fix it?

I am currently building Tetris on the command line, and I'm working with getch() to recieve input without a deliminating character and without pausing the code to take input. However, when I enable the function with initscr(), all my output is lost.

#include <ncurses.h>
#include <iostream>

using std::cout;
using std::endl;

//created variables, set up, etc etc

int main(){

  initscr();
  cbreak();
  keypad(stdscr, TRUE);
  noecho();

  while (true){
    cout << "hello" << endl; //complex things are printed here
    int input;
    while (true){
      input = getch();
      if (input == -1){
        break;
      } else {
        return 1; //my initial goal was just to get getch() to work, so the input reponse is to end the program
      }
    }
    cout << "goodbye" << endl; //other complex things are printed here
  }
  return 0;
}

Without initscr() turned on, all my output printed (but getch() didn't work). With it, I get a blank screen. Why is this happening, and how can I fix it?

boost::flyweight -- Who is attempting to call compare::operator()() with two arguments of type boost::flyweights::detail::ref_counted_value<>? [closed]

I'm getting a compiler error because somebody is attempting to call

template<typename KEY, typename VALUE>
bool compare::operator()(
    const boost::flyweights::detail::refcounted_value<VALUE, KEY>&_r0,
    const boost::flyweights::detail::refcounted_value<VALUE, KEY>&_r1
) const;

I cannot figure out, who is attempting to do this. I'm passing the compare functor to boost::flyweights::set_factory<compare>. The same error happens with both compilers, visual C++ and g++-10.

The class in question (refcounted_value) is an internal class used by flyweight and I'm not referring to it directly.

The error is caused by my functor not providing this method. Everything compiles if I do.

I would like to answer this question, if the local block-kapos let me!

mercredi 7 juin 2023

boost.test: problems with test source code that uses `chrono` and defines a test suite

My setup:

My test file:

// test.cpp
#define BOOST_TEST_MAIN
#define BOOST_TEST_MODULE a_nice_testing_attempt
#include <boost/test/included/unit_test.hpp>  // this is available

BOOST_AUTO_TEST_SUITE(MyNiceTestSuite)  // (*)

#include <chrono>
// actually I want to test much more, but I narrowed
// the problem down to this minimal snippet

BOOST_AUTO_TEST_SUITE_END() // (*)

Then I try to compile as: g++ test.cpp -o test.exe

And get a bunch of errors (>1700 lines to be precise). Here's some at the very top:

In file included from C:/msys64/mingw64/include/c++/12.2.0/bits/chrono.h:37,
                 from C:/msys64/mingw64/include/c++/12.2.0/chrono:39,
                 from test_main.cpp:17:
C:/msys64/mingw64/include/c++/12.2.0/ratio:58:24: error: expected template-name before '<' token
   58 |     : integral_constant<intmax_t, (_Pn < 0) ? -1 : 1>
      |                        ^
C:/msys64/mingw64/include/c++/12.2.0/ratio:58:24: error: expected '{' before '<' token
C:/msys64/mingw64/include/c++/12.2.0/ratio:63:24: error: expected template-name before '<' token
   63 |     : integral_constant<intmax_t, _Pn * __static_sign<_Pn>::value>
      |                        ^

And some from the bottom:

C:/msys64/mingw64/include/c++/12.2.0/bits/chrono.h:1371:47:   required from 'static MyNiceTestSuite:
:std::chrono::time_point<MyNiceTestSuite::std::filesystem::__file_clock, _Dur> MyNiceTestSuite::std:
:filesystem::__file_clock::_S_from_sys(const MyNiceTestSuite::std::chrono::time_point<MyNiceTestSuit
e::std::chrono::_V2::system_clock, _Dur2>&) [with _Dur = MyNiceTestSuite::std::chrono::duration<long
 long int, MyNiceTestSuite::std::ratio<1, 1000000000> >]'
C:/msys64/mingw64/include/c++/12.2.0/bits/chrono.h:1338:27:   required from here
C:/msys64/mingw64/include/c++/12.2.0/bits/chrono.h:1020:16: error: cannot convert '__time_point' {ak
a 'MyNiceTestSuite::std::chrono::time_point<MyNiceTestSuite::std::filesystem::__file_clock, int>'} t
o 'int' in return
 1020 |         return __time_point(__lhs.time_since_epoch() -__rhs);
      |                ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      |                |
      |                __time_point {aka MyNiceTestSuite::std::chrono::time_point<MyNiceTestSuite::s
td::filesystem::__file_clock, int>}

If I remove the lines marked with the astherisk (i.e. BOOST_AUTO_TEST_SUITE related), then it compiles without a problem. Unfortunately I am unable to progress from here and my question is rather vague:

  • what is going on here and how could I solve it?

How to create SWIG mapping for std::shared_ptr

What should be the proper SWIG mapping for the following function?

std::shared_ptr<double> getMinScale() const;

mardi 6 juin 2023

Integrating C++ Code into Node.js Application

I'm currently working on a Node.js project, and I've encountered a scenario where I have some computationally intensive tasks that could benefit from being written in C++. I understand that Node.js can interact with C++ through native addons using the Node.js Addon API and the N-API.

Before I continue, I have a few questions:

How does Node.js interact with C++? Does it call C++ functions directly from JavaScript, or is there some message-passing or event-driven interaction?

Are there any performance overheads to calling C++ code from Node.js, and if so, what are they?

How do I handle error propagation from the C++ code to the Node.js layer? Can I use JavaScript promises and async/await in this context?

How do you handle memory management when passing data between JavaScript and C++?

Are there any best practices or common pitfalls I should be aware of when integrating C++ code into a Node.js application?

I have read the Node.js documentation regarding add-ons, but I am looking for some practical advice and possibly some sample code to help clarify these concepts.

Thanks a lot :)

Node.js version: v14.15.4

Operating System: MacOS Catalina 10.15.7

C++ compiler: GCC 8.3.0

How to use lambda functions in C++11?

I have an object that needs a function passed to it in order to work. Something like

int doSomething(string a, int b, string(*lookUpFunction)(string a, int b)) {
    return lookUpFunction(a,b).length():
}

This is simplified to just include needed parameters and correct return types. I believe I have defined this correctly but please correct me if I am wrong. lookUpFunction takes a string and an int and returns a string.

Where my problem comes in is using this function. I would think I would use like this

class x {
    DataBase* db;
public:
    int myFunc();
}


int x::myFunc() {
    return doSomething("a",1,[this](string a, int b)->string {
        return db->someFuncThatTakesStringAndInt(a,b);
    });
}

But my IDE throws errors. If I remove "this" it says db isn't accessible. With it in it says the lambda function is not castable to correct format.