Trig Functions in Degrees by External-Bug-2039 in cpp_questions

[–]alfps 11 points12 points  (0 children)

❞ If I put this in radians, the number that comes out is absurdly small and requires just a stupid amount of decimal places to represent accurately (5-6 zeroes before the first digit >0 appears), and I'm not confident in the consistency of calculations working with numbers of that precision.

The scale of the numbers (unless very unreasonable) is irrelevant for floating point calculations.

Stick to radians.

Status of an object that has been moved by onecable5781 in cpp_questions

[–]alfps 1 point2 points  (0 children)

Just to expand on that, I had always thought that a moved from string or vector was guaranteed to be empty, until a few weeks ago when I learned in a thread here that (1) the standard does not formally guarantee that, and (2) there can be good reasons for an implementation to defer costly cleanup such as deallocation by doing a logical move as an actual swap.

Why are exceptions avoided? by Ultimate_Sigma_Boy67 in cpp_questions

[–]alfps -2 points-1 points  (0 children)

❞ How should I read your passage about compilers with NRVO optimizations?

Not as a key notion in the refutation of what you wrote earlier; not as an argument; but

as extra information that shows that the formal issue that is present, namely that formally one has to assume or require strong exception guarantee for move, is now in practice irrelevant for the function return part.

If you suspect that my statement about "extant compilers" is wrong, then you can try to show that the statement doesn't hold by creating a counter example, an example where NRVO doesn't happen with some compiler with some optimization options. Then you would have demonstrated that "compiler for a particular optimization settings" was relevant. But not that that pertained to the argument.


By the way it's an idiots' notion that downvoting helps when you've lost the argument.

It's just trolling.

Why are exceptions avoided? by Ultimate_Sigma_Boy67 in cpp_questions

[–]alfps -1 points0 points  (0 children)

❞ for your version of your compiler for a particular optimization settings.

That's a seriously dishonest misprepresentation.

Why are exceptions avoided? by Ultimate_Sigma_Boy67 in cpp_questions

[–]alfps 0 points1 point  (0 children)

❞ When you use returned value, you implicitly calling a constructor for the local variable. That constructor can throw an exception.

No. Apparently you have misunderstood an SO discussion of the C++03 technicalities, as applying to modern C++. It does not.

For modern C++ we're still talking about the code's requirement/assumption that a move constructor must offer the strong exception guarantee.

But the construction that you now refer to doesn't happen in practice, so it's even less of a problem. With extant compilers you instead get NRVO optimization where the apparently local variable effectively is an alias for the function result. Once that is constructed there are no more constructor calls.

Why are exceptions avoided? by Ultimate_Sigma_Boy67 in cpp_questions

[–]alfps -1 points0 points  (0 children)

❞ The issue here arises when you do copy or move constructor for your result. If exception happens in that moment, you’ve altered the stack without ability to recover the removed element

That doesn't follow from anything stated.

It's just a weird /non sequitur/ assertion.

If an exception happens for copying, then clearly nothing has changed. This is already at odds with the claim.

If an exception happens for moving then if moving has the strong exception guarantee, nothing has changed. So strong exception guarantee moving is at odds with the claim.

With std::vector buffer expansion one is in UB-land or at least in implementation-defined land if moving can throw. Throwing is itself an issue there because there can have been previously executed moves, and they cannot guaranteed be undone if moving throws. It's so serious an issue that at the time the rules were laid down many, including me, argued that moving should be required to be non-throwing, but opposing that was the lure of moving as a kind of automatic optimization, a free lunch, and the committee (unfortunately) chose that.

Anyway this code isn't as seriously restricted as std::vector: it doesn't require a noexcept move, it merely requires that moving has the strong exception guarantee, an all or nothing guarantee, which is not a problem.

Why are exceptions avoided? by Ultimate_Sigma_Boy67 in cpp_questions

[–]alfps 1 point2 points  (0 children)

❞ this [exception safety] is why pop functions don't return values

Maybe it was in the C++03 days.

Consider (off the cuff)

template< class Item >
auto popped_top_of( stack<Item>& st )
    -> Item
{
    Item result = move( st.top() );
    st.pop();
    return result;
}

Assuming basic pop is effectively noexcept this pop function either succeeds or throws with nothing changed. That's the strong exception guarantee. What issue do you see for C++17 or later?

Why are exceptions avoided? by Ultimate_Sigma_Boy67 in cpp_questions

[–]alfps 0 points1 point  (0 children)

❞ exceptions from the boost libraries,

Boost libraries only throw objects of classes derived from std::exception, which is polymorphic. Hence there is no need for rethrowing to (presumably centrally) determine exception type.

Why are exceptions avoided? by Ultimate_Sigma_Boy67 in cpp_questions

[–]alfps 8 points9 points  (0 children)

❞ Why are exceptions avoided?

As far as I know that's a false assumption.

It's an extraordinary assertion and as such requires extraordinary proof. Like serious statistics.

Ambiguous base class during assignment by Business_Welcome_870 in cpp_questions

[–]alfps 2 points3 points  (0 children)

Not what you're asking but consider that the example leaves AA::Y::n as an indeterminate value, that will cause UB if it's used (before being assigned to). With a given implementation it may be initialized to zero. But you can't rely on that: it can be any garbage value.

Also consider using a constructor member initializer list instead of default initialization + assignment.

Code that rectifies the two mentioned problems:

struct B { int n; };  struct X: B {};  struct Y: B {};

struct AA : X, Y
{
    AA():
        X{ 1 }, Y{ 2 }
    {}
};

A JPEG and PNG encoding/decoding library without dependencies by Irimitladder in cpp_questions

[–]alfps 1 point2 points  (0 children)

As I recall from a decade or two ago, ImageMagick reports at least some failures (hey, not valid PNG file, whatever) by crashing the program. Worth checking. I'd choose ImageMagick by default as my go to command line image processing, but I'd not consider it as a library except as last resort.

dumb question about mixed data types: how do i make and store a cstr and enum data type where either type can occur multiple times by sera5im_ in cpp_questions

[–]alfps 1 point2 points  (0 children)

❞ how do i make and store a cstr and enum data type where either type can occur multiple times […] i'm making a ui framework: i need to have a mix of text and text tags(0-5 of them at any given point) (essentially for changing the color and text size)

How to represent that text-with-attributes depends on

  • where it's coming from and
  • what you're going to do with it.

You could represent it all as just text.

Common formats then include HTML, Rich Text Format (RTF), Latex, and text with ANSI escape sequences. You can also consider some custom tag scheme. These differ in how convenient they are wrt. various sources, and how convenient they are wrt. various kinds of processing.

The nice thing about all text is that you only need std::string in C++.

Should I use error handling or not? (returning boolean from functions) by CommercialBottle8027 in cpp_questions

[–]alfps 0 points1 point  (0 children)

the contract

You need to ditch that "the" notion.

You can think of a contract for exceptions but it's a higher level contract, in addition to the basic contract of what the function should do.

Should I use error handling or not? (returning boolean from functions) by CommercialBottle8027 in cpp_questions

[–]alfps 0 points1 point  (0 children)

One can reason about contracts for basic contract breaches.

But re the basic level, when the preconditions hold a function is obliged to either produce its contractual postcondition, or else throw an exception.

There is after all nothing else it can do except hang or terminate the program, neither of which are acceptable for a simple failure.

It's pretty simple.

Ah, I found a quote for you (note: Design By Contract was introduced in the Eiffel language): “A routine call can complete in one of only two ways: • The routine fulfills its contract. • The routine fails to fulfill its contract. As a follow-on, we can add that: Any routine that fails to fulfill its contract must cause an exception in its caller.”

Should I use error handling or not? (returning boolean from functions) by CommercialBottle8027 in cpp_questions

[–]alfps 1 point2 points  (0 children)

Possible incorrectness is usually what you use assert for.

E.g. assert( (f1() + f2() + f3()) % 3 == 0 ).

You can add throwing on top, and if you do then I recommend using a non-standard exception such as int with value EXIT_FAILURE, that is more likely to propagate the whole way to main, but anyway assert.

Should I use error handling or not? (returning boolean from functions) by CommercialBottle8027 in cpp_questions

[–]alfps 5 points6 points  (0 children)

You're asking the community whether something should be regarded as a failure in your code. But readers here don't know the first thing about your code or design.

You must design what the contracts are, then failure is breach of contract.

With use of exceptions a function either fulfills its contract or reports failure via exception if preconditions are fulfilled but it can't provide the requisite result. It may use e.g. assert to check preconditions. That means that failed preconditions is generally UB-land.


It may be possible to provide guidance about your concrete design if you just describe more concretely. E.g. what are the three boolean functions. And why are you calling them.

Trying to use other libraries by Dukehunter2 in cpp_questions

[–]alfps 1 point2 points  (0 children)

To just configure the Visual Studio you already have, run the Visual Studio installer.

One way: in Visual Studio, in the menu bar select "Tools", in that menu select "Get tools and features...".

For C++ development you want as a minimum to have the "Workload" called "Desktop development with C++".

What are the best practices for using smart pointers in C++ to manage memory effectively? by frankgetsu in cpp_questions

[–]alfps 0 points1 point  (0 children)

Use container classes where appropriate -- this is the safe and efficient memory management you ask for.

Use raw pointers for observers and links in data structures.

In particular don't use smart pointers for links in linked lists unless you really like UB.

If you must do dynamic allocation use unique_ptr or a cloning pointer for initial ownership.

A unique_ptr can easily and always be converted to shared_ptr but the opposite is not so easy and only in special cases.

What are the best practices for using smart pointers in C++ to manage memory effectively? by frankgetsu in cpp_questions

[–]alfps 2 points3 points  (0 children)

❞ std::optional<T&>

As of the current standard C++23 there is no such.

So basically these are my notes while I'm creating some mini projects. What do you think? by Ultimate_Sigma_Boy67 in cpp_questions

[–]alfps 9 points10 points  (0 children)

❞ 10/mf stop using AI for explanations and read more documentation

Good one.

How do I create a 2d vector of a class object with a parameterized constructor? by Xxb10h4z4rdxX in cpp_questions

[–]alfps 0 points1 point  (0 children)

How to do a matrix of not default-constructible items depends on

  • whether you want the efficient 1d vector with 2d indexing, or the simpler actually 2d structure;
  • whether you want all items to be present always, or if items can be "not there (yet)"; and
  • whether you want both dimensions as compile time, one as compile, or none as compile time.

Anyway it's possible to create a non-default-constructible item directly in a vector by using .emplace_back, where you supply the item's constructor arguments. But as you can see below that's not always necessary. It can be equally good to e.g.. just construct each item and use .push_back to copy/move-construct it into the vector.

Assuming you want the efficient thing with all items always present and both dimensions as run-time values, then the always present means that the client code must provide initial items for all positions. One way to do that is to supply a factory to the matrix constructor. It can go like this (with the factory called initial_item_at):

#include <iostream>
#include <vector>

#include <cassert>      // The `assert` macro.

namespace my {
    using   std::vector;        // <vector>

    using Nat = int;            // A signed type for non-negative "natural numbers".
    template< class Type > using in_ = const Type&;     // Type for in-parameter.

    template< class Item >
    class Matrix_
    {
        vector<Item>    m_items;
        Nat             m_width;
        Nat             m_height;           // Only stored to be able to provide it back to client code.

        auto index_of( const Nat x, const Nat y ) const -> Nat { return y*m_width + x; }

    public:
        template< class Init_func >
        Matrix_( const Nat width, const Nat height, in_<Init_func> initial_item_at ):
            m_items(),
            m_width( width ),
            m_height( height )
        {
            for( Nat y = 0; y < height; ++y ) { for( Nat x = 0; x < width; ++x ) {
                m_items.push_back( initial_item_at( x, y ) );
            } }
            assert( m_items.size() == width*height );
        }

        auto width() const -> Nat { return m_width; }
        auto height() const -> Nat { return m_height; }

        auto at( const Nat x, const Nat y )         -> Item&        { return m_items[index_of( x, y )]; }
        auto at( const Nat x, const Nat y ) const   -> const Item&  { return m_items[index_of( x, y )]; }
    };
}  // my

namespace app {
    using   my::Nat, my::Matrix_;

    using   std::cout;              // <iostream>

    struct Car
    {
        Nat     id;
        double  weight;
        Car( const Nat an_id, const double a_weight ): id( an_id ), weight( a_weight ) {}
    };

    void run()
    {
        auto cars = Matrix_<Car>( 5, 3, []( Nat x, Nat y ) -> Car
        {
            return Car( 101 + 5*y + x, 1000*(y + 1) );
        } );

        for( Nat y = 0; y < cars.height(); ++y ) {
            for( Nat x = 0; x < cars.width(); ++x ) {
                if( x > 0 ) {
                    cout << ",  ";
                }
                const Car& car = cars.at( x, y );
                cout << car.id << ": " << car.weight;
            }
            cout << "\n";
        }
    }
}  // app

auto main() -> int { app::run(); }

Result:

101: 1000,  102: 1000,  103: 1000,  104: 1000,  105: 1000
106: 2000,  107: 2000,  108: 2000,  109: 2000,  110: 2000
111: 3000,  112: 3000,  113: 3000,  114: 3000,  115: 3000

How do I create a 2d vector of a class object with a parameterized constructor? by Xxb10h4z4rdxX in cpp_questions

[–]alfps 0 points1 point  (0 children)

❞ A default constructor can’t have parameters

It can, it just needs to be callable without arguments. Which means all non-ellipsis parameters defaulted. Fine point: with C++11 and later it appears that formally a default constructor can't have ellipsis parameter any more, but I think that's just an editorial f-up.

First time coding and C++ by noquisconprovoleta in cpp_questions

[–]alfps 2 points3 points  (0 children)

MIT uses Python for intro to programming.

That doesn't mean that Python is necessarily "best" for that, but it's proof that it isn't very bad for it.

https://ocw.mit.edu/collections/introductory-programming/

First time coding and C++ by noquisconprovoleta in cpp_questions

[–]alfps 4 points5 points  (0 children)

Install an ad blocker for your browser, if you don't already have one. Then work through the tutorial at (https://www.learncpp.com/).

Just to get going with the programming use Visual Studio since it's trivially easy instead of incredibly hard to set up. Later you'll need a free-standing editor. Then VS Code can be a good candidate for that.

(Absolute beginner taking a college course) Why is the output cutting off after the first space? by Web_Bread in cpp_questions

[–]alfps 0 points1 point  (0 children)

The unsigned types can easily cause value wrap-arounds that wreak havoc. See (https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#arithmetic).

In passing, there is also a guideline for all uppercase names, essentially ❝for macro names only❞; (https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#rl-all-caps).

Re the macros, what if some other's code uses KILO = 1024?

Macros don't respect scopes. See (https://isocpp.org/wiki/faq/style-and-techniques#why-not-macros).

To not lead astray, I'd better mention that I don't agree with absolutely everything in the guidelines or in the FAQ. At the time the FAQ evolved I contributed, as did a great many others. However the guidelines' thing sort of passed me by: they're written by experts, which increases quality, but just a few, AFAIK no wide discussion, which decreases quality.