Programming thread

There's also copy elision, which is one of the exceptions to the as-if rule. The compiler is allowed to replace a copy assignment/construction with a move assignment/construction for optimization purposes, even if copying has observable side effects.
I wrote a little test program about just that yesterday and found that clang strangely seems to bypass both the move and copy constructors/assignments for temporary values. It seemed as if it was initializing the values in place, and so I didn't mention it since I didn't really know how to quantify the behavior properly.
 
  • Like
Reactions: SIGSEGV
I wrote a little test program about just that yesterday and found that clang strangely seems to bypass both the move and copy constructors/assignments for temporary values. It seemed as if it was initializing the values in place, and so I didn't mention it since I didn't really know how to quantify the behavior properly.
What you're describing sounds like return value optimization, but it's hard to say for sure without seeing your test program. It's definitely some form of copy elision, though:
1587572491264.png


Remember, kiwis: cppreference is a much better source of documentation for the C++ standard library than cplusplus.com is.
 
Pass objects by reference unless the function absolutely has to have its own copy.
Question, since I'm not a C(++): isn't it preferable when doing multi-core programming to pass small objects by value? Although they're copied it's better than escaping to the heap, no?
 
Question, since I'm not a C(++): isn't it preferable when doing multi-core programming to pass small objects by value? Although they're copied it's better than escaping to the heap, no?
Fundamental types (i.e., integral types, floating point types, and pointers) should definitely be passed by value unless the function absolutely needs to modify the original variable. I said to "pass objects by reference" because fundamental types aren't generally thought of as objects in regular conversation (the C/C++ standard, however, uses "object" to describe pretty much anything with a memory address). A good rule of thumb would be "if sizeof(type*) is greater than or equal to sizeof(type), pass type by value" or something.
 
Pass objects by reference unless the function absolutely has to have its own copy.
Fundamental types (i.e., integral types, floating point types, and pointers) should definitely be passed by value unless the function absolutely needs to modify the original variable. I said to "pass objects by reference" because fundamental types aren't generally thought of as objects in regular conversation (the C/C++ standard, however, uses "object" to describe pretty much anything with a memory address). A good rule of thumb would be "if sizeof(type*) is greater than or equal to sizeof(type), pass type by value" or something.
I'd add to this that if you're passing by reference, unless you specifically intend for your function to modify the original object, declare it as a reference to a const so that your function explicitly isn't allowed to modify it.
 
I'd add to this that if you're passing by reference, unless you specifically intend for your function to modify the original object, declare it as a reference to a const so that your function explicitly isn't allowed to modify it.
Temporaries can't be bound to non-const lvalue references, so there's also a practical reason to include the const qualifier beyond clarifying your intent to the compiler/other people.
 
  • Like
Reactions: Yotsubaaa
What you're describing sounds like return value optimization, but it's hard to say for sure without seeing your test program. It's definitely some form of copy elision, though:
View attachment 1247793

Remember, kiwis: cppreference is a much better source of documentation for the C++ standard library than cplusplus.com is.
I second that, cppreference is infinitely better. And yes, that is the manifested behavior.

-=-=-=-=-=-=-=-=-=

On a semi-similar note, I am continuing to develop my own language and am looking for some opinions.
One thing I still haven't settled on is how to handle returns. Eventually I want to add a jitter, but in the interests of ease of development it's dynamically executed for now, and that means having a consistent function structure. For the moment I've decided that a call may have a single argument —which may be a tuple, facilitating multi-argument calls— and may return a single smart pointer.

My issue is one of safety, consistency, and efficiency, currently I return values by smart pointer, but I am considering adding a return-destination as an optional argument, and having functions allocate their result to it. The issue is, while this is theoretically more efficient than passing a smart pointer around, it makes it harder to enforce scoping guarantees, and moves certain responsibilities from the caller to the callee. An additional concern is that the system is supposed to roughly parallel a c-like abi so that it can be jitted.

C++:
// Rough interface

// Shadows the stack and holds details like named variables, permissions etc.
// Acts as a reverse single-linked-list, allowing the stack to be traversed
struct InvocationContext;

// Holds type details
struct TypeHandle;

// Allocates objects when supplied a type
struct ObjectAllocator;

// Pairs a pointer with a type
struct ObjectHandle
{
    // Untyped pointer to the object
    void* handle;
    // The type of the object
    TypeHandle type;
};

// A simple smart pointer type
struct ReturnHandle
{
    // The contained object
    ObjectHandle object;
    // The allocator it was created from
    ObjectAllocator* allocator;
   
    ~ReturnHandle();
};

// Represents the details of a function invocation
struct Invocation
{
    // The context the invocation takes place in
    InvocationContext* context;
    // The argument to the function
    ObjectHandle argument;
    // The result of the function
    ReturnHandle result;
};

// A function
struct Function
{
    // Actual implementation uses function pointers in place of virtual tables, simplified for brevity
    virtual void Invoke(Invocation& invocation)=0;
};


// A basic addition function for integers
struct AddIntsFunction : public Function
{
    void Invoke(Invocation& invocation) override final {
        // Get the context
        InvocationContext& context = *invocation.context;
       
        // Try to treat the argument as a tuple and extra two integers from it
        auto&& [argA, argB] = ExpandArgumentTuple<int, int>(context, invocation.argument);
       
        // Do our calculation
        int result = argA + argB;
       
        // Get the allocator for locals
        auto& allocator = context.getLocalAllocator();
        // Create an object handle from a lifted int, with the int type
        ObectHandle marshalledResult{allocator.Allocate<int>(result), GetType<int>()};
        // Set our invocation result
        invocation.result = ReturnHandle{marshalledResult, &allocator};
    }
};


// Function can be called from c++ like this;
InvocationContext context{/*Construction details omitted*/};

int a = 3, b = 5;

// Create our tuple
Tuple argTuple{GetObjectHandle(a), GetObjectHandle(b)};

// Specify our invocation
Invocation invocation{&context, GetObjectHandle(argTuple), {}};

AddIntsFunction{}.Invoke(invocation);

// Retrieve the result
int result = GetObject<int>(context, invocation.result.object);

// Notes;
//    The aforementioned function only works on ints, so in practice a meta function is used which
// deduces the correct add function by inspecting the operands' types before calling it.
//    The C++ api is somewhat cumbersome, but a bytecode IL is already underway.
The alternative system would effectively be copy elision, but with the potential of returning through multiple scopes. What I don't like is that the callee then has to manage those aspects of scoping.
Does anybody have any criticisms or a better solution?
 
Last edited:
  • Thunk-Provoking
Reactions: SIGSEGV
Today I had a random insight while programming. I created a pointer in a struct to another struct, and for a second I was wondering if this indirectness will have any adverse effects. And then it dawned on me: if I was programming in any OOP language and not in C, I would be constantly creating pointers to pointers to pointers to pointers...

That leads to my question: do you think that experience in programming in C is transferable to OOP languages, or because they are so different it doesn't really count?

I am not sure about that.
 
  • Thunk-Provoking
Reactions: Yotsubaaa
Clang is cool but I fucking hate how it pretends to be MSVC on windows setting macros and there's no way to turn it off short of recompiling.
From what I've heard, what compatibility they have is OK but there are several MSVC libraries they can't re-implement due to patent issues and it's been fucking with me.
If you attempt to compile an SDL program it fucks up because with MSVC SDL tries to include sal.h which is patent protected and thus fails, what the fuck were they thinking?
 
Today I had a random insight while programming. I created a pointer in a struct to another struct, and for a second I was wondering if this indirectness will have any adverse effects. And then it dawned on me: if I was programming in any OOP language and not in C, I would be constantly creating pointers to pointers to pointers to pointers...

That leads to my question: do you think that experience in programming in C is transferable to OOP languages, or because they are so different it doesn't really count?

I am not sure about that.
I totally get this. I went from oop to the modular type. Its a different shift. You'll pick OOP up just fine because there are a lot of concepts that are still present in higher level and gen purpose languages.
 
What's the difference between C, Objective C, C++ and C#? When I first heard of standard C, my first thoughts were "that must be some primitive fucking caveman shit that can't even work on modern computers" but the general theme I've seen in passing is that as time marches forward, newer programming languages are less sophisticated then what came before.
 
What's the difference between C, Objective C, C++ and C#?
I don't know Objective-C, but roughly:
C is a relatively low-level language (as things go these days) where you manage the memory, threads, etc. yourself. You're typically working directly with variables, pointers, blocks of memory, etc. There's a type system, but it's more of a gentlemen's agreement than binding law.
C++ is (roughly) a superset of C that adds in a bunch of new features, most importantly classes. This allows you to create data types that have logic associated with them and automatically manage their memory to some degree. The type system has been extended to handle classes and their interrelationships.
Almost any non-barbarian C program is also valid C++.

C# is a completely different animal - while the syntax is similar to C/C++, the execution environment, memory model, type system, etc are different. Memory is garbage-collected rather than managed by the programmer, and you're abstracted away from the details of memory, object representations, addresses, and so on. C# and its environment will also do much more "magic" for you behind the scenes than C/C++ will, and its common libraries are more extensive than those languages'.

That's my very brief summary anyway.
 
I don't know Objective-C, but roughly:
C is a relatively low-level language (as things go these days) where you manage the memory, threads, etc. yourself. You're typically working directly with variables, pointers, blocks of memory, etc. There's a type system, but it's more of a gentlemen's agreement than binding law.
C++ is (roughly) a superset of C that adds in a bunch of new features, most importantly classes. This allows you to create data types that have logic associated with them and automatically manage their memory to some degree. The type system has been extended to handle classes and their interrelationships.
Almost any non-barbarian C program is also valid C++.

C# is a completely different animal - while the syntax is similar to C/C++, the execution environment, memory model, type system, etc are different. Memory is garbage-collected rather than managed by the programmer, and you're abstracted away from the details of memory, object representations, addresses, and so on. C# and its environment will also do much more "magic" for you behind the scenes than C/C++ will, and its common libraries are more extensive than those languages'.

That's my very brief summary anyway.
Does C++ let you go the the same depths of programming memory and threads as C?
 
Does C++ let you go the the same depths of programming memory and threads as C?
Yes. Every standard C program can be rewritten in C++ with very little change. The one thing you could hit is that some environments may support C but not C++, e.g. the Linux kernel. The converse is possible but more rare.

Let's start some shit while we're at it:
C++ is bloated af and I pity the ones who have to rely on it. It compiles slow, has a thousand and one gotchas, and does not offer anything over plain old C. I write elegant, hobby programs in C and that's so much smoother than swimming in STL vomit. It's also easier to learn because there's less cognitive load. Sure, you can monkey-train yourself into writing working C++ and I've done that, but that's due to the absolute state of the world, not to the inherent qualities of C++.
 
and does not offer anything over plain old C
Destructors are nice, and making up (simple) classes is nice. That is, compared to how you'd implement them in C.
But I agree about the bloat. If you show me something with multiple inheritance, template """wizardry""", lambdas (which I can't believe are part of the language now), friend classes, those weird first-generation "almost-smart" pointers, etc. you better bring your fireproof clothes.
 
Yes. Every standard C program can be rewritten in C++ with very little change. The one thing you could hit is that some environments may support C but not C++, e.g. the Linux kernel. The converse is possible but more rare.

Let's start some shit while we're at it:
C++ is bloated af and I pity the ones who have to rely on it. It compiles slow, has a thousand and one gotchas, and does not offer anything over plain old C. I write elegant, hobby programs in C and that's so much smoother than swimming in STL vomit. It's also easier to learn because there's less cognitive load. Sure, you can monkey-train yourself into writing working C++ and I've done that, but that's due to the absolute state of the world, not to the inherent qualities of C++.
I don't think anyone would disagree with you there. Bjarne Stroustrup bolted every language feature he'd ever heard of onto C to create C++, and the language suffered for it.
 
**All hypothetical **

I have a couple of questions:
If I am currently building out shit right now and I'm looking at sniffing gsm packets using (https://shop.hak5.org/products/hackrf) for this.

I heard that 5g isn't going to be utilizing gsm packets anymore, is that true? And if so, is there any leads on how to sniff out 5g cell packets? And the information coming over the wire, are there any ways to see device information and not chipset information?
 
  • Thunk-Provoking
Reactions: CockPockets
Does someone know how I can use the MediaWiki software to create an offline wiki for my own writings?
 
Back