Giter VIP home page Giter VIP logo

cppinaction's Introduction

CC BY-SA 4.0

CppInAction

Demo Code for presentation "Contemporary C++ In Action"

This code does not compile without the missing pieces (the precompiled modules mentioned in the code) because it is for educational purposes only. Besides that it is complete.

The missing pieces are:

  1. Asio, preferably non-Boost Asio
  2. libav FFmpeg
  3. SDL2 SDL
  4. argparse argparse
  5. modularized standard library

I have forked

  1. Asio, branch 'module'
  2. SDL2, branch 'module'
  3. argparse, branch 'module'
  4. libav, branch 'module'

plus

  1. a modularized standard library with a polyfill for the missing, not yet implemented parts: std.module

which contain the necessary changes to compile Asio, SDL, libav, and argparse as modules. My take on the C++ standard library module adds Casey Carter's current implementation of <generator>, plus my implementation of <print> and a partial implementation of C++26's explicit lifetime management P2590 on top of the standard library that comes with the compiler toolset of your choice.

There is also a minimum set of sources from FFmpeg v6.0 to compile module libav. You need to provide the necessary link libraries yourself if you want to build the executable.

The videos of the keynote presentations are here:

Building the app

Windows

Update 4 or better is highly recommended.

  • open a VS2022 command line window
  • cmake -B bld-msvc -G Ninja -Wno-dev -DCMAKE_CXX_STANDARD=23 --fresh
  • ninja -C bld-msvc

MSYS2 (UCRT64)

Clang 16.0.2 or better is required.

  • open a MSYS2 window
  • export CC=clang
  • export CXX=clang++
  • cmake -B bld-clang -G Ninja -Wno-dev -DCMAKE_CXX_STANDARD=23 -DCMAKE_CXX_FLAGS="-stdlib=libc++" --fresh
  • ninja -C bld-clang

Linux

Clang 16.0.2 or better is required. Clang 17 is recommended.

  • open a terminal window
  • export CC=clang-1x
  • export CXX=clang++-1x
  • cmake -B bld -G Ninja -Wno-dev -DCMAKE_CXX_STANDARD=23 -DCMAKE_CXX_FLAGS="-stdlib=libc++" --fresh
  • ninja -C bld

License

This work is licensed under a Creative Commons Attribution-ShareAlike 4.0 International License.

CC BY-SA 4.0

cppinaction's People

Contributors

danielae avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

cppinaction's Issues

MSys2 build not working

Hi,

Thanks for all your hard work you're been doing on modules. It's been incredibly useful in getting started on using them in my clang builds in Linux.

I've gotten stuck on using them on Windows though. I've tried creating a MSys2 (tried ucrt and clang64) build of CppInAction following the instructions and I've gotten stuck on it. I've attached a build log.

build.log

It looks like the version of std::string that argparse adopts through header inclusion doesn't match up with the version i'm getting from import std;. But it's not clear to me why.

Problem with c_resource

Preamble

Hi, @DanielaE I was really enjoying your presentation "Contemporary C++ in Action" especially when you talked about using C libraries and wrapping them up to make them more safe to use. After that i checked out this source code to figure out how it actually works. Now i want to:

  1. Report possible bug
  2. Spin some discussion about c_resource and/or wrapping C libs in general.

Bug part

Assumptions

  1. This application code, although is somewhat "small example" still should handle error case scenarios.
  2. c_resource assumed to be used in general case, where construct function (from C library) for resource allocation may fail.
  3. Such failures, especially allocation failures assumed to be handled properly and not cause any undefined behavior.

Potential bug in error handling

libav::Packet Packet;
libav::Frame Frame;
int Result = 0;
while (not atEndOfFile(Result) and successful(av_read_frame(File, Packet))) {
const auto PacketReferenceGuard = Packet.dropReference();

  • If av_packet_alloc function returns NULL because of failure (and it can do that, the documentation is explicit about it:"An AVFrame filled with default values or NULL on failure."
  • Packet object with inner tPacket type object will have null pointer as ptr_ field
  • Packet object will transfer this null value pointer by cast operator constexpr operator U *(this Self && self) when calling av_read_frame (File, Packet)
  • This will trigger null pointer de-reference inside of library code.
  • Because inside of library it calls read_from_packet_buffer - which de-references a pointer without check for null, or it will try to access to the field of this structure, without checking for null in else branch.

I assume it should have had same kind of check as

if (have(Decoder)) {

but for libav::Packet and maybe even for libav::Frame in decodeFrames function.

And if this really a bug, and I'm not wrong in my assumptions:

  • It's sneaky
  • this kind of mistake would be not uncommon and have noticeable impact on server side stability/correctness if applied at scale, exposing some room for exploitation
  • It would be hiding in corners sometimes - when streams of error cases are mixed with streams of "filter by property" cases, and not exposing itself - until some zeroday.

Suggestions

If we talking not about general rethinking of c_resource approach, but fixing what we have in this particular case i would suggest.

  1. Add customization point (macro or link time or template) when building for "test" purpose - not just call allocation function each time, but inserting NULL returns as failure on purpose. Test final application behavior with -fsanitize=address,undefined flags, test application under valgrind, providing different frequency of such allocation errors, from all of them failing, and till one in N calls failing.
  2. Having in mind all cases found by previous step and by manual inspection of all usages of c_resource, add proper calls to have(resource) so it is in valid state before it used. Repeat step 1 to see changes.
  3. Make interface of c_resource more thin, not allowing usage of de-reference/pointer acquisition when inner state is NULL without triggering assertion. Can be achieved with just addition of regular asserts, or by using not_null pointer type wrapper in places.
  4. Unit tests? fuzzing of inputs? Maybe mutation based testing?
  5. Maybe add some caveats/warnings about state of such implementation in readme/slides/comments.

Wrapping C API discussion part

For sake of usability c_resource template class is accumulating at least 3 different reasons to "have" or don't "have" inner (pointer) in it:

  • The first is success/failure of construct function.
  • The second is move semantics.
  • The third is programmers good/evil will.

No doubt usability really shines, when you can just do this kind of manipulations:

auto makeFrames(fs::path Directory) -> std::generator<video::Frame> {
auto PreprocessedMediaFiles = InfinitePathSource(std::move(Directory))
| vws::filter(hasExtension(".gif"))
| vws::transform(tryOpenAsGIF)
| vws::transform(tryOpenVideoDecoder)
;

But i think it only works on somewhat small scale example, which doesn't bother to separate reasons why its internal pointer is not there anymore.
Is it because:

  1. Path is empty:
    if (not Path.empty() and
  2. Or because emplace failed (and why it failed)
    successful(File.emplace(Filename.c_str(), nullptr, nullptr))) {
  3. Or because we didn't find any GIFS there or we found one, but failed because of something else?
    File = acceptOnlyGIF(std::move(File));

So it's breaking single responsibility principle for code. It clamps down 3 different channels of "why" question into 1 bit of informational answer "have or doesn't have pointer value inside". At glance it looks like boost::outcome or std::optional, std::unique_ptr and gsl::not_null all married together inside of this implementation.

Because access to underlying pointer is not guarded by thin interface with preconditions and invartiants, like when using assertions, bugs can propagate through system unnoticed. While mixing semantically meaning of error case with filter case will add more problems debugging or even noticing logic errors or unhandled errors.

So in "easy to use, hard to misuse" - it definitely has "easy to use" part, but hard to misuse, and widening of error case channel of information (without big reworks of code), i think still somewhat lacking.

What are your thoughts? Do you have any suggestions about good resources/presentations/examples/practices for programmers trying to wrap C libraries in contemporary C++ at scale and with correctness and performance in mind? Thank you for your time!

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.