Programming Confessions Thread



  • We're just rolling out our own hand-made licensing system in our software.

    The worst bit is that I actually believe that this is a good idea (for various non-strictly code-related reasons).


  • Considered Harmful

    5 days in production, 2 mil. jobs processed, then - BAM! 💥 -

    internal uint GetJobCount(bool Lock = true)
    {
        if (Lock)
        {
            uint Result = UInt32.MaxValue;
            bool LockTaken = false;
            try
            {
                Monitor.TryEnter(Jobs.Worker.Lock, (int)NC_LOCK_TIMEOUT, ref LockTaken);
                if (LockTaken)
                    Result = Jobs.Worker.Current;
            }
            finally
            {
                if (LockTaken)
                    Monitor.Exit(Jobs.Worker.Lock);
            }
            return Result;
        }
        else
            ; // Redacted
    }
    
    // Elsweyr
    
    if (GetJobCount() > Config.MaxJobsPerWorker)
        BasicallyScrewYou(); // HTTP 429
    

    Yes, entirely my fault. I really should not be allowed near code :headdesk:🔫



  • @Applied-Mediocrity So if I'm reading this right, the first time it 1) gets called with lock: true and 2) Monitor.TryEnter fails to acquire the lock, it returns MAXINT and the user gets

    ❓


  • Considered Harmful

    @Mason_Wheeler Yep. The lock timeout is generous, so races were successful for days until it keeled over. Could have been discarded, but! returning HTTP error is very fast (vs sitting in the queue + doing the job). It so happens that some of our customers are... well, special (there's always one asshole in the family) and simply continue "banging on the door", cue the avalanche. Doesn't excuse my fuckery...


  • Notification Spam Recipient

    @Applied-Mediocrity said in Programming Confessions Thread:

    It so happens that some of our customers are... well, special (there's always one asshole in the family) and simply continue "banging on the door", cue the avalanche.

    Those that do so get added to the ban list and fun stuff gets sent to them instead, a la:

    https://www.youtube.com/watch?v=4OztMJ4EL1s

    Especially around the 30-minute mark.

    You can try this in action by visiting https://dev-masterserver.hypatia.timefirevr.com/ 😉 . It should ban you after about 10 rapid requests (it uses a leaky bucket rate limiter if memory serves). Doesn't work so well if you randomize your IP address, but meh.


  • 🚽 Regular

    @Applied-Mediocrity said in Programming Confessions Thread:

    Yes, entirely my fault.

    For declaring local variables with an initial capital letter? Unforgivable. 🏆


  • Considered Harmful

    @Tsaukpaetra Oh there is rate limiting, but it's not turned on. These are customers with SLAs. Others don't even get past the FW, nor soft IP check if when FW is misconfigured. Technically bombing the service means we can ban them, also technically 429 effectively does it already, also also technically we have to provide three nines (planned), four nines (unplanned) uptime. In practice disputes are solved (for certain meaning of the word) in shouting matches between the bigwigs on conference calls 😶

    @levicki@Zecc said in Programming Confessions Thread:

    For declaring local variables with an initial capital letter? Unforgivable.

    uint dwResult = UInt32.MaxValue;
    bool bLockTaken = false;
    

    Fixed! :trollface:


  • Notification Spam Recipient

    @Applied-Mediocrity said in Programming Confessions Thread:

    @levicki@Zecc said in Programming Confessions Thread:

    For declaring local variables with an initial capital letter? Unforgivable.

    uint dwResult = UInt32.MaxValue;
    bool bLockTaken = false;
    

    Fixed! :trollface:

    No nonono, it's:

    uint dwTheResultWeNeedToReturn = UInt32.MaxValue;
    bool bIsTheLockTakenAlreadyYet = false;
    

    Gotta have alignment, see...?



  • @Tsaukpaetra said in Programming Confessions Thread:

    @Applied-Mediocrity said in Programming Confessions Thread:

    @levicki@Zecc said in Programming Confessions Thread:

    For declaring local variables with an initial capital letter? Unforgivable.

    uint dwResult = UInt32.MaxValue;
    bool bLockTaken = false;
    

    Fixed! :trollface:

    No nonono, it's:

    uint dwTheResultWeNeedToReturn = UInt32.MaxValue;
    bool bIsTheLockTakenAlreadyYet = false;
    

    Gotta have alignment, see...?

    E_USE_APPS_HUNGARIAN_NOT_SYS_HUNGARIAN



  • @Tsaukpaetra Downgrading me to SSLv3 was a nice touch.


  • BINNED

    @Vixen said in Programming Confessions Thread:

    @Tsaukpaetra said in Programming Confessions Thread:

    @Applied-Mediocrity said in Programming Confessions Thread:

    @levicki@Zecc said in Programming Confessions Thread:

    For declaring local variables with an initial capital letter? Unforgivable.

    uint dwResult = UInt32.MaxValue;
    bool bLockTaken = false;
    

    Fixed! :trollface:

    No nonono, it's:

    uint dwTheResultWeNeedToReturn = UInt32.MaxValue;
    bool bIsTheLockTakenAlreadyYet = false;
    

    Gotta have alignment, see...?

    E_USE_APPS_HUNGARIAN_NOT_SYS_HUNGARIAN

    E_USE_NEITHER_OF_THAT_SHIT_ITS_NOT_THE_NINETIES_ANYMORE


  • Fake News

    @topspin Apps Hungarian notation is all about prefixing variables with prefixes that make sense and which you "standardize" within your project, but not any further than that.

    Stuff like e.g. always consistently using (xSomething / ySomething) for coordinates as a matter of style, rather than using a haberdashery of names like offsetXAxisSomething, horizontalPosSomething, etc.


    The problem with Systems Hungarian Notation (adding stuff like "lw" etc to indicate C's variable type) was that it didn't really make sense and was elevated to "industry best practice" status where suddenly no exceptions can exist. When good advice suddenly no longer has a rule attached where it should apply, it becomes dangerous dogma.

    So Systems Hungarian Notation sure can die in a fire, but that doesn't mean the Apps Hungarian Notation is necessarily bad.



  • @topspin said in Programming Confessions Thread:

    @Vixen said in Programming Confessions Thread:

    @Tsaukpaetra said in Programming Confessions Thread:

    @Applied-Mediocrity said in Programming Confessions Thread:

    @levicki@Zecc said in Programming Confessions Thread:

    For declaring local variables with an initial capital letter? Unforgivable.

    uint dwResult = UInt32.MaxValue;
    bool bLockTaken = false;
    

    Fixed! :trollface:

    No nonono, it's:

    uint dwTheResultWeNeedToReturn = UInt32.MaxValue;
    bool bIsTheLockTakenAlreadyYet = false;
    

    Gotta have alignment, see...?

    E_USE_APPS_HUNGARIAN_NOT_SYS_HUNGARIAN

    E_USE_NEITHER_OF_THAT_SHIT_ITS_NOT_THE_NINETIES_ANYMORE

    E_BULLSHIT

    Read this, then come back and we can continue conversation. https://www.joelonsoftware.com/2005/05/11/making-wrong-code-look-wrong/

    use hungarian notation to tell me what KIND of thing the variable is.

    uint dwX;
    uint dwXOffset;
    

    tells me that's it's a "double word" (despite being a uint) and the name says it's an X coordinate.

    so with that is this code correct or not?

    uint dwDeltaX = dwX - dwXOffset;
    

    it looks correct, but actually it's not!

    because dwX measures a X coordinate in the reference frame of the screen and dwXOffset measures an x coordinate in the DOCUMENT reference frame! the compiler tols you nothing, and because you used Sys Hungarian the notation told you nothing!

    0296dfb2-5ee3-4beb-80b5-2ce72cb35b98-image.png

    If, on the other hand you had done this:

    uint scrnX;
    uint docXOffset;
    

    and let the compiler/intelisens tell you the data storage type of the variable you would instantly see that this is calculating bollocks

    uint docDeltaX = scrnX - docXOffset;
    

    This is what hungarian notation was SUPPOSED to be, to tell you what KIND of thing the variable was, not what it's data storage type was!

    Even back when SysHungarian was adopted by Microsoft the compiler and IDEs of the day were more than capable of handling the data storage conversions and mismatches. so there never was any point at all using SysHungarian. AppsHungarian which tells you the name of the variable AND what its context is.... now that is useful! even today!


  • Notification Spam Recipient

    @TwelveBaud said in Programming Confessions Thread:

    @Tsaukpaetra Downgrading me to SSLv3 was a nice touch.

    Hmmm, now. that was unintended.


  • BINNED

    @Vixen said in Programming Confessions Thread:

    Read this, then come back and we can continue conversation. https://www.joelonsoftware.com/2005/05/11/making-wrong-code-look-wrong/

    What's recommended there will have to do if you're still stuck coding in C (see "it's not the nineties anymore"), but if you're using a modern programming language with static typing and without implicit conversion you can do better than make wrong code look wrong; you can make it not compile.


  • Discourse touched me in a no-no place

    @Vixen said in Programming Confessions Thread:

    uint dwX;
    

    tells me that's it's a "double word" (despite being a uint) and the name says it's an X coordinate.

    No, the name says it's X. It doesn't say what that X is.


  • Discourse touched me in a no-no place

    @loopback0 said in Programming Confessions Thread:

    @Vixen said in Programming Confessions Thread:

    uint dwX;
    

    tells me that's it's a "double word" (despite being a uint) and the name says it's an X coordinate.

    No, the name says it's X. It doesn't say what that X is.

    Often that's obvious from the application. If it isn't in this case, X is insufficient to satisfy Apps Hungarian requirements.

    Yes, you sometimes need to rename things when the app changes. That's what you have an IDE for (among others).



  • @antiquarian said in Programming Confessions Thread:

    you're using a modern programming language with static typing and without implicit conversion you can do better than make wrong code look wrong; you can make it not compile.

    Ah, the Rust approach. Python3 did this for bytes and strings, and nothing else. The theory being you can do implicit conversion relatively safely for almost all things, but there's no right way to convert bytes to a string without knowing the encoding. I guess? Word of Guido.

    On the other hand, for this example, you're advocating document coordinates and window coordinates have different types? And that I cast back and forth from (documentcoordint) and (windowcoordint)?



  • @AyGeePlus I've read people talking about "primitive obsession" and how it's a bad thing to use int for something if you could possibly make a new type for it...even if it's going to be used as an int everywhere, including for basic math operations. I'm not convinced, mainly because it seems like tons of boilerplate to rewrite all the math operations and handle all the edge cases, plus the possible(?) performance hit of boxing and unboxing.



  • @Benjamin-Hall It makes the abstract type system wonks happy when you do that, which is a particularly virulent kind of degenerative brain disease. You will have to write (windowPixel) document_pixel_x all the time anyway, and if you can't be trusted to remember your variable names what hope do you have of doing typecasts correctly?

    The opposite extreme is of course people who do uint data[5000]; //should be enough .

    I think of them as zombies and vampires: both dangerous and should be put to death, but you will need different weapons.

    @Benjamin-Hall said in Programming Confessions Thread:

    possible(?) performance hit of boxing and unboxing.

    The minecraft revision post-Notch converted all the functions with the signature foo(params,float x, float y, float z) to foo(params,Vector3 pos). Unboxing in java is expensive(especially in every inner-loop function) to the tune of 30% longer frames.



  • @AyGeePlus said in Programming Confessions Thread:

    You will have to write (windowPixel) document_pixel_x all the time anyway,

    Shirley the Right Way™ would be something like var winPos = new WindowPosition(document_pixel_x, document_pixel_y) and use winPos.x wherever you need it, rather than casting the one thing all the time, wouldn't it?



  • @AyGeePlus said in Programming Confessions Thread:

    Unboxing in java is expensive(especially in every inner-loop function) to the tune of 30% longer frames.

    wow, you'd think that something that would be happening like all the time would be better optimized than that.



  • @Vixen I'm kind of suprised it wasn't more. Allocating and deallocating thousands of three-byte arrays is pathological abuse of memory management. Passing integers by value on the stack is much less memory, and you never have to access the actual values stored at the pointer you're working with (which may be out of cache).



  • @AyGeePlus JAVA: If you wanted it done fast, you should have just had a Coffee instead.



  • @Benjamin-Hall said in Programming Confessions Thread:

    @AyGeePlus I've read people talking about "primitive obsession" and how it's a bad thing to use int for something if you could possibly make a new type for it...even if it's going to be used as an int everywhere, including for basic math operations. I'm not convinced, mainly because it seems like tons of boilerplate to rewrite all the math operations and handle all the edge cases, plus the possible(?) performance hit of boxing and unboxing.

    The boilerplate and additional compilation time is a real problem, but in terms of runtime performance, it can actually be a negative-cost abstraction due to different types not being able to be aliased and thus allowing for better optimizations. There was a talk at a C++ conference a couple years ago about it and they showed how using unique wrapper types actually resulted in more optimal generated machine code because of this. (The example used integers for a quick and dirty demo, but you can imagine this with bigger types like strings). So not only do you get the benefit of the compiler catching mistakes, you get better runtime code as well. The only cost is the boilerplate and added compilation time. Hopefully those can both be reduced with new language features (or new languages).

    For languages that aren't Rust or C++ though, well, I have no idea how the performance will work out. Probably best left to language features instead of trying to do it by hand with boilerplate.


  • Fake News

    @AyGeePlus said in Programming Confessions Thread:

    On the other hand, for this example, you're advocating document coordinates and window coordinates have different types? And that I cast back and forth from (documentcoordint) and (windowcoordint)?

    It depends on whether you need raw performance of course, but implementing dedicated types can keep things clearer, at the cost of making math somewhat more awkward because you should either call methods like windowPos.Add(windowCoordDiff) or use custom operators where order of operands matters to trigger the right one.

    However, if dedicated types work e.g. for date-time logic, why couldn't it be used in a UI context? The biggest hurdle is the integration problem: there's so much stuff out there that's not going to use your system of dedicated types, and that's when unboxing is going to hurt you when you're interfacing.

    EDIT: Also don't forget that "document coordinates" and "Window coordinates" might not have the same scale or use a different 0,0 point, so having dedicated types might be nice to hide all the conversion logic.


  • BINNED

    @AyGeePlus said in Programming Confessions Thread:

    On the other hand, for this example, you're advocating document coordinates and window coordinates have different types? And that I cast back and forth from (documentcoordint) and (windowcoordint)?

    Yes, as long as the casts are explicit. I was thinking along the lines of Haskell's type system. Ada has something similar, except it's a procedural language instead of functional and a lot more verbose.


  • BINNED

    @AyGeePlus said in Programming Confessions Thread:

    (windowPixel) document_pixel_x

    And right there you've made wrong code look wrong. Isn't that what you wanted? To prevent mixing these two kinds of coordinates as that is probably a bug.

    Anyways, in my opinion, either you'll use these things often enough that it justifies creating different types (or similar mechanism) to prevent mixing them up, or this is just a one off occurrence and then it also doesn't justify adding to your system of Hungarian notation and documenting it for everybody to use application-wide. What, you didn't intend to do that anywhere else outside that one function? Well, then I wouldn't call it Hungarian notation but rather descriptive variable names. Also, if you have dozens of confusingly named variables in your function that you can't keep track which does which, maybe it's time to refactor.


  • ♿ (Parody)

    I'm having fun learning how to get stuff done with Angular.


  • 🚽 Regular

    @boomzilla I feel the same about .Net. There's a certain level of frustration from feeling I have been out of this loop for a while and now I have a lot to catch up, but at the same time I am learning about so many new software libraries.

    And of course, if I didn't masochistically enjoy a certain level of frustration, I wouldn't be a software developer.


  • ♿ (Parody)

    @Zecc said in Programming Confessions Thread:

    And of course, if I didn't masochistically enjoy a certain level of frustration, I wouldn't be a software developer.

    Mostly, this. Figuring something out after banging my head against a wall for a while is super rewarding.

    Plus a change is nice now and then.



  • @boomzilla said in Programming Confessions Thread:

    Plus a change is nice now and then.

    Yup! I recently moved from Windows (using various C++ frameworks) to Linux using Qt. (I kept the C++ consistent!)


  • Notification Spam Recipient

    @boomzilla said in Programming Confessions Thread:

    Figuring something out after banging my head against a wall

    There are easier ways to make a glory hole...



  • @Tsaukpaetra He didn't say which head


  • Notification Spam Recipient

    @hungrier said in Programming Confessions Thread:

    @Tsaukpaetra He didn't say which head

    My point exactly.



  • Forgive me, colleagues, for I have sinned.

    A few years ago I was given a piece of lab equipment, an oscilloscope, a request to "make a DLL that's easily callable from LabVIEW 2010" and a pat on the back. So I took my copy of K&R ("easily callable from LabVIEW means a simple ABI, and that means C, right?") and tried to deliver it. I felt very inspired and not at all afraid to reinvent a few wheels in the process.

    The device in question speaks SCPI and has settings, some of them global, other belonging to each of its outputs. I decided that I needed one getter function and one setter function per one setting of the device ("simple", right? right?!); I also needed to enumerate all getters and setters at runtime to implement functions like "save all settings to a file". I also heard about new and exciting things like DRY and X-macros.

    So let's make an array of descriptors of all the settings:

    #define PROPERTY_TABLE \
    p_enum_perou   (output_state,  ":output?:state",  ab1234_enabled  ) \
    p_double       (global_period, ":output0:period", 8               ) \
    p_enum         (global_mode,   ":output0:mode",   ab1234_out_mode ) \
    p_int_perou    (channel_widget_counter, ":output?:wcounter"       ) \
    p_double_perou (frobnication_width, ":output?:width", 8           ) \
    /* more to follow ... */
    

    Some settings should be translated into enums, so we'll have to store the possible values in the table, too:

    static const char* ab1234_out_mode_string[] = {
    	"FOO", "BAR", "BAZ", "QUUX"
    };
    
    struct ab1234_property ab1234_properties[] = {
    	#define p_double(name, path, precision) { path, NULL, precision, type1234_double, 0 },
    	#define p_double_perou(name, path, precision) { path, NULL, precision, type1234_double, 1 },
    	#define p_enum(name, path, type) { path, type ## _string, sizeof(type ## _string)/sizeof(*(type ## _string)), type1234_enum, 0 },
    	#define p_enum_perou(name, path, type) { path, type ## _string, sizeof(type ## _string)/sizeof(*(type ## _string)), type1234_enum, 1 },
    	#define p_int_perou(name, path) { path, NULL, 0, type1234_int, 1 },
    	PROPERTY_TABLE
    	#undef p_double
    	#undef p_double_perou
    	#undef p_enum
    	#undef p_enum_perou
    	#undef p_int_perou
    };
    #undef PROPERTY_TABLE
    
    

    Let's remember the indices into this array:

    #include "property_table.h"
    enum ab1234_property_idx {
    	#define p_double(name, path, precision) cmd1234_ ## name,
    	#define p_double_perou(name, path, precision) cmd1234_ ## name,
    	#define p_enum(name, path, table) cmd9200_ ## name,
    	#define p_enum_perou(name, path, table) cmd1234_ ## name,
    	#define p_int_perou(name, path) cmd1234_ ## name,
    	PROPERTY_TABLE
    	#undef p_double
    	#undef p_double_perou
    	#undef p_enum
    	#undef p_enum_perou
    	#undef p_int_perou
    	ab1234_properties_size
    };
    #undef PROPERTY_TABLE
    

    So now mydev_set_frobnicator_volume(double) can call a helper and pass it the index into the settings array along with the user-supplied value, while mydev_save_all_settings() can iterate over that array and call all the helpers. Except I didn't stop at that and also implemented all the getters and setters in terms of the same X-macro:

    #include "property_table.h"
    #define getset(type, name, member) \
    	type ab1234_get_ ## name(ab1234* state, enum ab1234_result * result) { \
    		return (type)get_1234_property(state, cmd1234_ ## name, result, ab1234_output_invalid).member; \
    	} \
    	enum ab1234_result ab1234_set_ ## name(ab1234* state, type val) {\
    		union ab1234_state_value v; \
    		v.member = val; \
    		return set_1234_property(state, cmd1234_ ## name, v, ab1234_output_invalid); \
    	}
    
    #define perout(type, name, member) \
    	type ab1234_get_ ## name(ab1234* state, enum ab1234_output ou, enum ab1234_result * result) { \
    		return (type)get_1234_property(state, cmd1234_ ## name, result, ou).member; \
    	} \
    	enum ab1234_result ab1234_set_ ## name(ab1234* state, enum ab1234_output ou, type val) {\
    		union ab1234_state_value v; \
    		v.member = val; \
    		return set_1234_property(state, cmd1234_ ## name, v, ou); \
    	}
    
    #define p_double(name, path, precision)       getset(double,    name, real)
    #define p_double_perou(name, path, precision) perout(double,    name, real)
    #define p_enum(name, path, type)              getset(enum type, name, integer)
    #define p_enum_perou(name, path, type)        perout(enum type, name, integer)
    #define p_int_perou(name, path)               perout(int,       name, integer)
    PROPERTY_TABLE
    

    Did I save myself some typing? Maybe. Does the result look horrible? Yes. Would a design with just a few functions like ab1234_set(enum ab1234_setting, double value) instead of a lot of functions like ab1234_set_setting(double value) have been better? Perhaps.


  • Notification Spam Recipient

    I am incredibly wanting the ability to initialize a base class's member from a derived class's definition.

    Looks like I'm going to have to memcpy a toss-away array in the derived constructor...



  • @Tsaukpaetra Can you go into a bit more detail about what you're trying to do? I can think of a few alternatives and I'm curious if any apply.


  • Notification Spam Recipient

    @LB_ said in Programming Confessions Thread:

    @Tsaukpaetra Can you go into a bit more detail about what you're trying to do? I can think of a few alternatives and I'm curious if any apply.

    Basically I'm making a pseudo event handler for Arduino. The main loop holds an array of base-object references and uses a member array on the base to determine if it should call associated functions. This determination should have a default but said default varies by module, and is further configurable at runtime.

    The problem being that I can't specify an initializer for a base-class member in a derived-class definition without merely shadowing it (and thence breaking the functionality).

    So far the entire system is 100 percent theoretical, the only thing I'm sure of at this point is that syntactically it's not invalid.



  • @Tsaukpaetra I assume you want to avoid having the base class write the array and then the derived class writing the array again? Maybe you could have protected constructors in the base class for the derived class to pass in an array as a parameter, and initialize the base class array from that parameter? It sounds like you don't need to check the content of that array until the object has finished calling all constructors through the whole hierarchy.


  • Notification Spam Recipient

    @LB_ said in Programming Confessions Thread:

    I assume you want to avoid having the base class write the array and then the derived class writing the array again?

    I suppose that would be an interesting side effect to avoid, but since initialization is happening once only it doesn't really matter.

    @LB_ said in Programming Confessions Thread:

    Maybe you could have protected constructors in the base class for the derived class to pass in an array as a parameter, and initialize the base class array from that parameter?

    This is almost-kinda what's being done, but technically the "default" being provided is a define expression.

    @LB_ said in Programming Confessions Thread:

    It sounds like you don't need to check the content of that array until the object has finished calling all constructors through the whole hierarchy.

    Kinda. I'm only providing default values, and then a crude deserialization is swept over the holding object (untested, of course) replacing the defaults of a custom configuration has been provided.


  • Discourse touched me in a no-no place

    @LB_ said in Programming Confessions Thread:

    Maybe you could have protected constructors in the base class for the derived class to pass in an array as a parameter, and initialize the base class array from that parameter?

    Can the passed-in array be on the stack in the scope of the subclass's constructor? If that works, it seems like the best option. Second best would be allocating the array in the superclass (using a requested size) and then filling it in the subclass constructor.

    It sounds like you don't need to check the content of that array until the object has finished calling all constructors through the whole hierarchy.

    That is a good idea anyway. Only the outermost class can possibly know when all the constructors have finished, after all.


  • Notification Spam Recipient

    @dkf said in Programming Confessions Thread:

    Second best would be allocating the array in the superclass (using a requested size) and then filling it in the subclass constructor.

    I believe that's what I'm doing at the moment, it's declared 3x2 in the base and in the sub it's copied over from a local array of the same size.


  • Discourse touched me in a no-no place

    This makes me feel so dirty...

    #if defined(__GNUC__) && __GNUC__ < 6
    #pragma GCC diagnostic ignored "-Wmissing-field-initializers"
    #endif
    

    It wouldn't even be necessary if some old versions of the compiler weren't being fucking retarded and one of those buggy versions weren't being used in our CI builds…



  • @dkf said in Programming Confessions Thread:

    if some old versions of the compiler

    That's always fun... Our coding standard says we can use C++11. One of our compilers for a QNX build is only "kind of" C++11. Which is always fun when you forget. The local build works fine (because we're working on the normal linux build). Jenkins throws a temper tantrum.


  • Notification Spam Recipient

    @Tsaukpaetra said in Programming Confessions Thread:

    Looks like I'm going to have to memcpy a toss-away array in the derived constructor...

    Spent four hours trying to figure out why it wasn't working until I read the docs (scary, eh?) and realized I had the Source and Destination parameters switched. :headdesk:

    Now to figure out why it's crashing while calling a function...


  • Notification Spam Recipient

    @Tsaukpaetra said in Programming Confessions Thread:

    Now to figure out why it's crashing while calling a function...

    Answer: Because I wasn't explicitly initializing an array of pointers to nullptr and thus the program believed an object was instantiated when it was in fact not.

    All in all, the number of actual bugs (for this part) is actually rather minimal, about four off-by-one errors, and a logic inversion. I'm kinda proud of myself. 🦆



  • @Tsaukpaetra said in Programming Confessions Thread:

    Looks like I'm going to have to memcpy a toss-away array in the derived constructor...

    @Tsaukpaetra said in Programming Confessions Thread:

    Spent four hours trying to figure out why it wasn't working until I read the docs (scary, eh?) and realized I had the Source and Destination parameters switched. :headdesk:

    Save yourself in the future with std::as_const for the source parameter, you'll get a compile error if they're in the wrong order. If you are stuck using C and not C++ you can use GCC language extensions to make your own generic macro version of it or just have an as_const_void function.


  • BINNED

    @dkf said in Programming Confessions Thread:

    This makes me feel so dirty...

    #if defined(__GNUC__) && __GNUC__ < 6
    #pragma GCC diagnostic ignored "-Wmissing-field-initializers"
    #endif
    

    If that makes you feel dirty, I need to confess that I have the following in my make flags:

     -Wno-missing-field-initializers # stupid warnings are stupid
    

    because:

    struct Foo {
        int x, y;
    };
    
    int main()
    {
        Foo a;          // not initialized
        Foo b{};        // initialized, no warning: x == 0, y == 0
        Foo c{1,};      // initialized, warning: x == 1, y == 0
    }
    
    

  • Notification Spam Recipient

    @LB_ said in Programming Confessions Thread:

    Save yourself in the future with std::as_const for the source parameter

    (since C++17)

    Wouldn't that be great?

    @LB_ said in Programming Confessions Thread:

    If you are stuck using C and not C++ you can use GCC language extensions to make your own generic macro version of it or just have an as_const_void function.

    I'm not sure I see the point....


Log in to reply