Hacker News new | past | comments | ask | show | jobs | submit | Bambo's comments login

I'm not sure if it is actively maintained, but another option for formatting C code is https://clang.llvm.org/docs/ClangFormat.html


Ah, thanks!!


A good way to learn more is to search for books about topics you're interested in e.g.; sqlite, zeromq, google testing libraries, opengl...

1. https://www.amazon.co.uk/Design-Patterns-Object-Oriented-Add...

2. https://www.oreilly.com/library/view/using-sqlite/9781449394...

3. https://www.glprogramming.com/red/

4. https://gameprogrammingpatterns.com/

5. https://zguide.zeromq.org/


Looking for CC, advice and bugs!


Looks reasonable! On a system with virtual memory, one popular trick is the "virtual ring buffer," which lets the reader and writer always access a contiguous region of the full requested length. The idea is to map the same backing store twice sequentially in virtual memory. It leads to a much simpler implementation, because you don't have to handle the edge cases that relate to wrapping around.

Sample implementation in C++17 here:

https://github.com/stanford-stagecast/audio/blob/main/src/ut...

https://github.com/stanford-stagecast/audio/blob/main/src/ut...


That is a very good idea.

You don't even need to double-map memory. Just make the ring buffer smaller than your actual buffer, and treat any overrun as if it had wrapped around, but really just write past the (official) end. You might waste a bit of space at the front when you do, just to keep the code simple, but if you didn't have some room to waste, you wouldn't be using a ring buffer.

Another way to simplify management is to give the ring buffer a power-of-two size, and make the head and tail counters 64 bits, masking off the high bits when actually looking at the buffer. They only ever increase.


One thing I found useful is instead of

  volatile T member;

  T access( void ) { return member; }
Use volatile on the functions instead:

  T member;

  T access( void ) volatile { return member; }
This has causes all access to this-> within the function to be volatile, including read_position, write_position, overrun_flag and data[].

When inlining these functions within other parts of the code, the compiler can hoist reads into registers from the non-volatile members unless you add the compiler barrier that @ghhhhhk8899jj mentioned.


"The Pragmatic Programmer" is much more detailed.


A problem with the chunk system is that i don't know how big a chunk is at the time it's declared?


I like to apply the things i learn and enjoy how they change the way i work or do tasks!


You can't implement the assertions at compile time since they are predicates evaluated at runtime. This is also why it is a performance hit on the code. I chose to use C-style macros because it is easier to debug than templates.


Yes OLD stores the value of the variable before the execution of the DO.

This is because all of the virtual methods that have been overriden are visited in order to gather their assertions, but not execute their DO(). So while the assertions are being collected it also collects OLD() values which then can be tested at the called virtual method in its ENSURE() clause.

OLD is a complicated mechanism to implement in C++ because it requires saving current variables at the same time deferring the code to be executed.

Using the OLD() and ENSURE() (along with the other) clauses together, is described as subcontracting where subclasses "require less" and "ensure more", given in the https://en.wikipedia.org/wiki/Object-Oriented_Software_Const... (first edition).


The exception throwing is a compromise, it allows you to view the stack trace in an IDE to find out which assertions failed.


Imagination, to come up with solutions!


Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: