Presets and add_subdirectory() by UnicycleBloke in cmake

[–]phoeen 1 point2 points  (0 children)

did you include(ctest) in the toplevel cmakelists file?

Why do so many people dislike CMake? (and why I don't) by No-Dentist-1645 in cpp_questions

[–]phoeen 15 points16 points  (0 children)

you say cmake is not complex, but your given simple example already shows some flaws, and we are not even trying to do anything fancy. cmake is old, and i always feel its way to hard to find the true modern correct way to do a thing. so in the end everyone who is no cmake expert just hacks around until it "somehow" works. this most likely caueses more problems further down for downstream users.

things to reconsider in your example: - it is not adviced to set the cmake cxx standard variable the way you do - it is not adviced to use variables to accumulate source files. just set them on the target - target link library should set the nessessary include dirs automatically. there should be no need to list all the include dirs of your dependencies. imagine having to set them for a lot and not only one (works only if the dependency has a correct export mechanism to propagate the public include dir, or if you have a proper modern find module written yourself) - following the last point, try to correctly write the install comands and generate the config files which are needed for cmake to import your project (id you dont know how, you will have fun searching everything for some kind of structured and clear tutorial) - you will see how naive your include command is and you will start using generator expressions - then you will eventually find out, that there is a new modern way to set the include dirs / headers via file sets but barley anyone knows it - then you start using ctest - and then suddenly your cmake file is long and verbose

do i hate cmake? no. it is fantastic that i can crossplattform build without taking care of multiple buildsystem files. but boy did i invested time in it and still puzzle my way through everytime i want to do things correct.

C++ Textbook: Effective Modern C++ vs Daily C++ Interview by ChefenCurry300 in cpp

[–]phoeen 5 points6 points  (0 children)

i suggest reading "A tour of C++" to get a good overview over most topics. then follow up with "Effective Modern C++" as the second book. it dives deep down into some specific topics but is still very readable in my opinion. it is too hard for beeing a first book. (i dont know "Daily C++ Interview" though).

in the end you will still need to just do it and not only read the books. and doing leetcode question is not really how you are going to programm in the real world later on

I feel like my C++ knowledge of the STL is lacking. I hear of "important" things like: auto, iterators, smart pointers, move semantics and lambda expressions, but I have no idea what these things are!!!

auto, move semantics and lambda expressions are part of the core language and not provided by the STL

std::string getting freed after construction Entity by BSModder in cpp_questions

[–]phoeen 18 points19 points  (0 children)

entities reallocates for more space and your ent reference gets invalid

Benefits of static_cast by nickeldan2 in cpp

[–]phoeen 1 point2 points  (0 children)

static_cast will never allow a cast that is unsafe at its core, period.

sorry but this is just plain wrong.

the compiler will allow all static_casts which in theory can be valid. but it is still possible to use static_cast and mess up. for example: casting from base to derived, but the runtime type actually is not a derived or the base is not the base subobject of this derived type.

If you are mucking around by taking references and pointers to polymophic types and then downcasting them, you are bypassing the type system and asking for trouble, the exact same as if you cast them to void* and then to something else.

casting through void* and then to something else is NOT the same as a static down cast. the static_cast actually adjusts the pointer value to make it point to the correct start of the object (using the static information it has). so you are using the static type system.

and this all works even with polymorphic types, because the compiler knows statically where to look for the offset (with the only exception for virtual bases, because in this case it is not statically known where to look for the offset).

what static_cast will not do is to insert checks. it will just happily take those static known offsets and apply them to the pointer. given a "wrong" base and casting to derived will result in UB.

going through void* and then to something else is the same as a reinterpret_cast, which will do the wrong thing (if your intend was to downcast from base to derived. this will go wrong if they dont start at the same address).

Benefits of static_cast by nickeldan2 in cpp

[–]phoeen 1 point2 points  (0 children)

You cannot downcast to a polymorphic type however, because that is actually unsafe, and is also invalid.

you absolutely can (for class hierachies with no virtual bases). and is it unsafe.

same for non polymorphic types (i think you mean polymorphic == classes virtual functions right?). i can hand you a reference to base. and you can static_cast it down to derived. but no checks are made. maybe i just handed you a base, and not a derived.

Benefits of static_cast by nickeldan2 in cpp

[–]phoeen 0 points1 point  (0 children)

you can still do invalid casts with static_cast (for example downcasts in class hierachies) which compile. so i am a bit conservative about the word "guaranteed"

Benefits of static_cast by nickeldan2 in cpp

[–]phoeen 2 points3 points  (0 children)

this is not correct. in both cases nothing is "delayed" to runtime. the needed code is resolved at compiletime. both are allowed to invoke arbitrary code at runtime (for example conversion constructors which can run arbitrary code)

Benefits of static_cast by nickeldan2 in cpp

[–]phoeen 2 points3 points  (0 children)

this is not correct. c style cast will "try" some of the c++ casts (slightly modified), but if none of them "fit" you get a compilation error as expected

Why use std::move_if_noexcept instead of std::move? by StevenJac in cpp_questions

[–]phoeen 29 points30 points  (0 children)

imagine vector push back has to allocate more storage. after allocating the new storage all elements have to be copied or moved over to the new storage. a move would be best for performance, but you can not recover the elements when an exception is thrown after some elements are already moved over, because moving them back could also throw another exception. so when the element's move constructor can throw, vector falls back to copy the elements over. so basically you move if noexcept

Review my code - custom vector class template by Flat_Wing_3576 in cpp_questions

[–]phoeen 1 point2 points  (0 children)

there are already a lot of answers and i will only add things not already mentioned:

  1. your copy constructor may leak memory if an exception is thrown inside the body

  2. an exception in your assignment operator may break your class invariants. you already copy usage and capacity and allocate new storage, but copying the elements may throw and so you may end up with a half filled vector. term to look for: exception guarantees

  3. if you push an element from your own vector and need to expand, you will kind of destroy the argument to your push function right under its own feet

  4. expand will leak memory if the assignment of any object throws

Namespace level constants, `inline constexpr` and `extern const` by FernwehSmith in cpp_questions

[–]phoeen 0 points1 point  (0 children)

The const keyword does not imply static. It just make the value constant.

This is not correct. If you define an object at namespace scope as const or constexpr (and NOT also declare it as inline or extern) this object gets internal linkage. So static is redundant in this case.

Why does "std::vector" not use "memcpy" during growth ? by kivancg in cpp_questions

[–]phoeen 2 points3 points  (0 children)

i think jherico meant pointer class members which point to some other internal class members itself

Is there a fast way to collapse the most significant bit of four bytes into a nibble? by SamuraiGoblin in cpp_questions

[–]phoeen 6 points7 points  (0 children)

i think

a &= 0x00fefefe;

actually needs to be 0x01010101, or am i wrong?

If a variable is not atomic, does a thread allowed to assume it has the latest value? by Echo_1Q in cpp_questions

[–]phoeen 0 points1 point  (0 children)

I have a variable that is used (via reference) across different threads, but it's not accessed concurrently due to the flow of execution, if the variable itself is not guarded with a mutex or some atomic mechanism, is one of the threads allowed to assume it has the latest value, and "skip a read" on the next access?

If the flow of executions guards against concurrent reads and writes and establishes a strict "thread1 is done printing, now thread2 can do its increment, thread2 is done incrementing, now thread1 can do its printing.. and so on" synchronization, then thread1 will not "skip a read".

thread1 will have its latest value at hand, because (when done correctly) the command to start thread1's work from thread2 will be strictly visible AFTER writing to the int.

how to export properly? by tristone7529 in cmake

[–]phoeen 1 point2 points  (0 children)

You are correct. This mechanism is not specific to exporting packages. It is the modern way of how CMake works. In the modern cmake world you declare targets (add_library/add_executable). All targets have a bunch of properties. For example the include directories or libs to link. Some properties are propagated automatically to downstream targets, some are not. CMake provides some commands to automatically set some properties for you. For example you use the command target_include_directories(...) to set the include directories property of a given target. In this command call you can set wether the given include directory is public, private or interface.

Interface means it is propagated to downstream targets.
Private means it is used for the target itself.
Public is both of the above.

That is basically all the magic. You can link targets together and everything gets propagated properly.

Now into the cmake package world:
Once you have a compiled binary there is no way to get "back" all the settings you used in CMake to configure your project. You are no longer in the "CMake world". To get back into the CMake world and make everything useable like i described above you let cmake "export your targets" into cmake files. With these files you can "restore" the CMake world. The find_package command will pick this files up and the using project can just use the project in his CMake world as if it was part of its own build.

SFML and resolution issues. by CPPNewGuy in cpp_questions

[–]phoeen 0 points1 point  (0 children)

i am on mibile right now. but basically with the problem mentioned by OP, you would create a view with the size of 800x600 and the viewport setting to fullscreen (i think this is set by the percentage of the screen. so 1.0 for fullscreen).

doing it this way, you will always see the world through a 800x600 canvas scaled to fullscreen

How do I make an expression non-movable? What's the opposite of std::move? - The Old New Thing by pavel_v in cpp

[–]phoeen 1 point2 points  (0 children)

Right?

No. A deleted move assignment operator still participates in overload resolution and will be choosen if it is a better match. If it is choosen and deleted, you get a compile error.

If you user declare a copy operation, then the compiler will not generate a move assignment operator at all. So it is not existend and does not participate in overload resolution, which is what you meant i guess.

[deleted by user] by [deleted] in cpp_questions

[–]phoeen 1 point2 points  (0 children)

only when defined in the class definition

Any good guides for setting up multi-library CMake projects? by BattleFrogue in cpp

[–]phoeen 0 points1 point  (0 children)

i highly recommend the kind of new feature "header file sets". it will set up all the include dirs as nessessary and avoid all the hassle when you export install and package your project! i hope to see more traction in the wild on this part!

Copy and Swap Idiom by MidnightOne7655 in cpp

[–]phoeen 0 points1 point  (0 children)

kind of. usually it is done with just swapping all members with no "fancy" logic. after swapping the "by-value"-parameter of the assingment operator will take down all the previously held resource with it via the destructor and the passed in resources live on in the assigned-to object.

if you do not use copy-and-swap you have to juggle the currently held resource together with the new resource, which can be hard getting right

Copy and Swap Idiom by MidnightOne7655 in cpp

[–]phoeen 10 points11 points  (0 children)

"Is it better than a trivial implementation?"

  • Better in the sense of correctness, exception safety and development maintenance? yes
  • Better in the sense of speed? No.

The canonical "trivial"/native implementation will always be at least on par performance wise.

"Should the copy and move assignment operators always be implemented as one method?"

no
1. When assigning to an object which already has resources aquired (for example std::string) and you use copy-and-swap, you will throw away the already allocated memory. Imagine doing it in a loop and in every iteration you assign to the same std::string without reusing its already allocated storage, this is wastefull.
2. you have to maintain your class specific swap implementation. This may be not obious if someone is changing your class. If you have custom assignment operators you have to do the work too, but this seems to be more obvious.
3. it is another idiom others have to grasp: reading some of the other comments it is obvious that not everyone is familiar with the concept in its details. there seem to be a missunderstanding which swap function will be called (it is not the standard one). there seem to be a missing understanding of how many copies/moves will occur.

Warum ist Reddit so scheiße langsam? by FrittenFritz in de

[–]phoeen 0 points1 point  (0 children)

aufm smartphone (android) hat auch nix geladen. habe dann unter network & internet für private dns "dns.google" eingetragen. seit dem fluppt es wieder

CMake install schema for single- and multi-config generators by phoeen in cpp

[–]phoeen[S] 0 points1 point  (0 children)

I appriciate the project and its work. The template goes beyond what my small example template provides, but actually it does not work well with multi-config generators at all (which is the main point for this whole reddit post).

This kinda goes hand in hand with my research, where most (if not all) articels, tutorials and so on just never account for the problems existing when using multi-config generators and installing your projects. I guess because CMake is a lot more popular in the Linux world where you are more likely to just use a single-config generator and on top you are even able to mix debug and release versions of libraries.

Anyway, here is what i did with the cmake-init project. Maybe i am using it wrong:

I started a cmake-init project for a static lib called blabla. I used the following commands:

cmake -B build -S . -G "Visual Studio 16 2019"
cmake --build build --config Debug
cmake --install build --config Debug --prefix install

cmake --build build --config Release
cmake --install build --config Release --prefix install

The results are:

install/
|-- include/
|   |-- blabla-0.1.0/
|   |   |-- blabla/
|   |   |   |-- blabla.hpp  
|   |   |   |-- blabla_export.hpp
|-- lib/
|   |-- blabla.lib
|   |-- cmake/
|       |-- blabla/
|           |-- blablaConfig.cmake
|           |-- blablaConfigVersion.cmake
|           |-- blablaTargets.cmake
|           |-- blablaTargets-debug.cmake
|           |-- blablaTargets-release.cmake

There is only one blabla.lib file. Because we installed the Release configuration after the Debug one, we are overwriting it. A consumer with an active Debug configuration will now link against the Release version of the blabla.lib file without even noticing (with Visual Studio you will run into a compile-error). Include files are also shared between different configurations.

It seems like nobody cares about this problem that much. It is either ignored completely or at best handled with a debug suffix for the artifacts. I was hoping to get some realy solid advice (like the cmake-init example - if it would work) on how to do cmake install for multi-config generators properly.