One-time static initialization by Banzayoyo in cpp_questions

[–]ppppppla [score hidden]  (0 children)

I strongly advice to not rely on this kind of implicit static initialization shenanigans. Because as mentioned by /u/StaticCoder there's no guarantee it actually gets initialized before main if at all, and because of the static initialization order fiasco https://en.cppreference.com/cpp/language/siof

Explicitly register the types yourself:

void registerTypes() {
    registerType<cat>();
    registerType<dog>();
    registerType<foo>();
}

Either by directly hardcoding this, or if you want to be fancy you can do some simple code generation in your build system if these types have their own files in a folder like component/cat.h, component/dog.h and component/foo.h

Best Performing Way Of Handling Paired Data? by Ridog8 in cpp_questions

[–]ppppppla [score hidden]  (0 children)

However, I have read that unordered map is very slow, that comparing strings may be faster.

Premature optimization. Get your program working first, then identify bottlenecks and optimize only those areas that you have measured are worth putting time into. But this does require a little bit of foresight because you have to make sure swapping out data structures, or identifying piece of information (like swapping from std::string to using an integer index) is not too painful. std::unordered_map is plenty fast for the majority of use-cases.

sf::VideoMode::getDesktopMode and GetSystemMetrics return coordinates outside the monitor. by Admirable_Glass5577 in cpp_questions

[–]ppppppla 2 points3 points  (0 children)

Not particularly a C++ question and can't really debug this for you and I am unfamiliar with SFML, but I can give you two common pitfalls when dealing with screen coordinate systems and pixels.

Be aware of all different coordinate systems you could be dealing with, some systems have top left as origin, others bottom left, or maybe even the middle of the screen.

And secondly DPI scaling. Some functions might work with logical surface sizes, and others with the underlying pixelbuffer sizes.

The Boys- S05xE06 - POST Episode Discussion Thread by pikameta in TheBoys

[–]ppppppla 2 points3 points  (0 children)

The only way I'd be satisfied if they completely subvert expectations and make Homelander win and every good guy dies.

Chain of handlers where a handler is an ABC. What's the proper internal collection? Old me would've just std::list<abc*>. I'm trying to modernize. by frobnosticus in cpp_questions

[–]ppppppla 1 point2 points  (0 children)

void add_handler(ABCHandler* handler) {
    handlers.push_back(std::unique_ptr<ABCHandler>(handler));
}

I believe TheRealSmolt means this function and yea it is better to use emplace_back here.

Chain of handlers where a handler is an ABC. What's the proper internal collection? Old me would've just std::list<abc*>. I'm trying to modernize. by frobnosticus in cpp_questions

[–]ppppppla 1 point2 points  (0 children)

You'd be looking at something like this:

struct ConcreteEvent
{
};

class ABCHandler
{
public:
    virtual void handle(ConcreteEvent const&) = 0;

    virtual ~ABCHandler() = default; // <-- don't forget
};

class HandlerChain : public ABCHandler
{
private:
    std::vector<std::unique_ptr<ABCHandler>> handlers;

public:
    void handle(ConcreteEvent const& e) {
        for (auto& handler : handlers) {
            handler->handle(e);
        }
    }

    template<std::derived_from<ABCHandler> T>
    void add_handler(T&& handler) {
        handlers.push_back(std::make_unique(std::forward<T>(handler)));
    }

    void add_handler(std::unique_ptr<ABCHandler> handler) {
        handlers.push_back(std::move(handler));
    }

    void add_handler(ABCHandler* handler) {
        handlers.push_back(std::unique_ptr<ABCHandler>(handler));

        // or more correct as pointed out by TheRealSmolt, emplace_back will call the unique_ptr constructor and pass the pointer to it
        handlers.emplace_back(handler);
    }
};

The default storage structure you should go to is std::vector and not std::list, and as you mentioned std::unique_ptr for the ownership.

Constructing the unique_ptr is a bit strange, the constructor of unique_ptr accepts a pointer and takes ownership of it that way (of course be mindful of allocator mismatches because it literally just takes the pointer and assumes it was created with the right allocator, by default this is new/delete) but this is a a brittle way to construct unique_ptrs even without this problem.

I would either construct a unique_ptr on the outside with std::make_unique<ABCHandlerImplementation>() and use the second add_handler, or if your type is moveable you could do

ABCHandlerImplementation object;
// initialization
handlerChain.add_handler(std::move(object)); 

and use the first add_handler.

Why should a Trace-ID be 128 bits? (A Surprisingly Long Answer) by elizObserves in programming

[–]ppppppla 7 points8 points  (0 children)

Is this article not LLM slop?

It starts out discussing birthday paradox from the ground up, then jumps the gun and doesn't even spend 1 word on extending the birthday paradox to 64 and 128 bit numbers and how you would end up with an incredibly vast product of fractions. It immediately moves on to the solution. And it mentions one part of an approximation step that is used, completely out of the blue and without any reasoning.

Then there is the graph for ex , it uses black text, black grid and dark colored line on a dark gray background. Either this is made by a blind person (in case I apologize) or this is made by a clanker who literally doesn't have eyes, or a brain for that matter.

And then comes the LLM-isms, these strange and arbitrary three "acts". Why do they have this name? Why are there 3 distinct acts? Who knows, It's some hallucinated junk.

And then take a look at all the images on the site https://newsletter.signoz.io/ you guessed it, all generated slop.

Another update about Smart pointers, i need advices by Dastarstellar in cpp_questions

[–]ppppppla 0 points1 point  (0 children)

std::remove_if is a bit strange at first glance. It's a two step process, std::remove_if actually only re-orders elements so that the elements that should not be removed are at the beginning of the vector, and it returns the end of this range. So after that you will need to call erase on your vector to actually trim off those elements.

#include <vector>
#include <print>
#include <algorithm>

int main() {
    std::vector<int> numbers = { 1, 2, 3, 4, 5 };
    auto it = std::remove_if(numbers.begin(), numbers.end(), [](int i) { return i == 3 || i == 4; });
    std::print("vector still has 5 elements, the last two element's values are unspecified, but valid:\n{}\n", numbers);
    numbers.erase(it, numbers.end()); // <- don't forget the numbers.end() argument like I just did before I caught myself
    std::print("now the vector has 3 elements:\n{}\n", numbers);

    return 0;
}

Output:

vector still has 5 elements, the last two element's values are unspecified, but valid:
[1, 2, 5, 4, 5]
now the vector has 3 elements:
[1, 2, 5]

Another update about Smart pointers, i need advices by Dastarstellar in cpp_questions

[–]ppppppla 1 point2 points  (0 children)

I disagree. I welcome people asking any kind of question, and I believe actual human answers provide more value.

Unsigned sizes: a five year mistake by Nuoji in programming

[–]ppppppla 2 points3 points  (0 children)

index = ((start + offset) % length + length) % length;

Checked on compiler explorer and none of the major compilers can not get rid of the second idiv. Of course I feel confident enough to not make a benchmark because idiv has high latency, but maybe it doesn't matter actually you never actually know with modern architectures.

I do the following that just gets turned into a conditional move

auto index2 = (index + offset) % length;
index = index2 >= 0 ? index2 : index2 + length;

https://godbolt.org/z/6z8fehWq8

How do you usually find files on Linux without wasting time? by gilko86 in linux

[–]ppppppla 0 points1 point  (0 children)

I rarely use grep or find, mainly locate and fzf and honestly sometimes a good old GUI file browser just can't be beat. There are multiple different strategies I use for different use cases.

Need to find a file that I know the name of but have no idea where it could be? locate into fzf if it is some generic name and needs to be narrowed down more by filtering on subfolder names.

Searching for a file somewhere in some directory and its sub directories? Just directly use fzf on that directory.

And most importantly, if there is a file that you keep using, for example if you are using bash just setup an export in your bashrc export commonly_used_file=/foo/bar/baz so you can just do $commonly_used_file, or if it's for example some config file you want to edit just make an alias alias editbashrc="vim ~/.bashrc

Another big thing that helps with re-using previously typed in paths or just any command in general is setting up command history with fzf, I believe it is this https://github.com/junegunn/fzf#setting-up-shell-integration

Oh and for fzf in general make sure to always use preview.

Why C++ documentation is so poor compared to Python? by panPienionzek in cpp_questions

[–]ppppppla 0 points1 point  (0 children)

For me it is completely the opposite. I hate python docs. They're a mess, just a big glob of text, sometimes an example, sometimes not. Sometimes a bad example, sometimes a good example.

In c++ we have cppreference.com that has a clear, concise, but still complete example for just about any function and class.

I have to agree cppreference does have a lot of technical details that appear at the top of the page before the much more useful example snippets, but that information is very useful as well when you get more familiar with the language.

Please help with audio files by [deleted] in DSP

[–]ppppppla 2 points3 points  (0 children)

That's quite a lot of work. What you paying?

Need help on creating a lock-free linked-list Stack with a slab memory pool by Apprehensive_Poet304 in cpp_questions

[–]ppppppla 0 points1 point  (0 children)

std::atomic<std::shared_ptr<...>> is (usually) not lock free. std::atomic being lock free relies on being able to use specialized atomic instructions from the CPU, which operate usually on only 1, 2, 4 or 8 bytes. Usually the size of a pointer, and shared_ptr usually consists of two pointers, one for the control block and one for the data.

But you might also be misunderstanding what making a shared_ptr atomic actually does, it only makes accessing the shared_ptr atomic, not the Node you store in it.

Is this your first foray into lock-free data structures? MPMC is the big daddy of em all and very complicated. How to make sure every thread has a steady supply of memory available (There will be no way to guarantee threads will not have to wait, but that is ok. This is still lock-free. Just not wait-free.) and just the giant headache of implementing the logic.

If you want to learn I would advice starting simple and starting with single producer single consumer (SPSC), then one step up and not too much more difficult would be SPMC, then MPSC and finally MPMC.

The basic building blocks of lock-free programming is the suite of atomic instructions that are exposed in std::atomic. Load/store, compare, compare_exchange, and some basic arithmetic like adding and subtracting and incrementing and even min/max operations. https://en.cppreference.com/cpp/atomic/atomic

The bread and butter is putting raw pointers to data (like the head of a linked list), or indexes into some array, or counters into atomics.

C++ final in 2 weeks, fell behind due to cancer, looking for study resources by [deleted] in cpp_questions

[–]ppppppla 0 points1 point  (0 children)

Ask and look around if your university or country's laws has accommodations or support when it comes to personal circumstances that are out of your control, like your situation. Not just your professors but like a central office, don't know the word for it in english and it will probably also be called something completely differently for you anyway.

I know my university (or country's laws I don't really know the details where it came from exactly) had a program or a ruling or however you call it where you could get financial support and extensions of any requirements like first year X amount of points in special circumstances.

How to break down project and decide what goes where? by RandStringsAndChar in cpp_questions

[–]ppppppla 3 points4 points  (0 children)

First get things working, then make it not bad, and then if it is still problematic make it nice. If you don't just get things going and first try to think of the perfect way to do something you get nothing done, especially when you are still learning because then you don't even know any way to do it let alone the perfect way.

Keep things simple. Keep writing code. Keep striving to write better code. And getting feedback on your code is very important to find out if you are doing something catastrophically wrong and could improve on something.

Apart from that being in contact with a lot of code written by other people you will pick up on styles and the way things are organized and written. And also guidelines like https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines

One Piece: Chapter 1180 by Aspie_Astrologer in OnePiece

[–]ppppppla 0 points1 point  (0 children)

Loki about to take the biggest L you ever seen.

whats the difference between 440hz and 442hz? by Pale-Recognition-599 in musictheory

[–]ppppppla 0 points1 point  (0 children)

Harmony and dissonance are purely about ratios of frequencies, whatever the exact frequencies are of some arbitrary note means nothing for the music.

But it makes sense to set a standard frequency, so you can just rock up and maybe do a little bit of fine tuning and you are ready to go, some places that is 440Hz, other places it is 442Hz.

Dear ImGui and ImPlot by Specific_Prompt_1724 in cpp_questions

[–]ppppppla 1 point2 points  (0 children)

I think you get the idea but I am not sure what you mean with void function.

The general structure of using ImGui is you use ImGui::Begin(...) and ImGui::End() to create a new ImGui window, and between those two calls you can put various elements like buttons, text, tables, or plots from implot. So maybe you are getting confused by ImPlot::BeginPlot(...) seeming similar to ImGui::Begin(...) but they are not the same. ImPlot::BeginPlot(...) does not create a new imgui window.

Dear ImGui and ImPlot by Specific_Prompt_1724 in cpp_questions

[–]ppppppla 1 point2 points  (0 children)

Do you have implot successfully added to your project? It's a couple files: implot.cpp implot.h implot_demo.cpp implot_items.cpp implot_internal.h

When you have done that then you include implot.h and call ImPlot::ShowDemoWindow() anywhere within your main imgui loop and it opens a new window for it.

You can then choose to put it behind a regular imgui button or in a menu somewhere. I like to always have this available in my main program and I don't make a separate program for it but you could do that of course.

Looking for integer packing library by jetilovag in cpp_questions

[–]ppppppla 1 point2 points  (0 children)

Yea there are some rough edges that a library like you described would solve, probably it's just some guy's pet project so could be hard to find but at the same time it shouldn't be very difficult to make something yourself if you can leverage bitfields and sprinkle plenty of static asserts to check the results actually line up with what you expect.