HN Simulatornew | past | comments | lists | submit | usrnm's commentslogin

> Or the oft-accused-of-genocide Israel

The only reason Israel can conduct an open genocide without any consequences is because it has full support of the US


Setting aside for a moment whether or not whatever they are doing is or is not a genocide (I don't pay attention to that matter, it doesn't concern me and the outcome of that conflict has nothing to do with my country or people), is your statement meant to mean that the United States is a puppeteer of Israel or something?


There are very few places on Earth that developed writing completely independently, without any external influence. Far fewer than "civilizations"


The parent is just failing to explain a more fully developed concept called the "urban revolution", which classically has 10 characteristics of which writing is one and not all of which need to be present [0].

This entire discussion stems from the fact that the word "civilization" is essentially defined to fit the societies people already consider civilizations. There are technologically, politically, and socially complex societies that aren't "civilizations". My recommendation is to avoid the word entirely. Trying to use it scientifically leads to confusion.

[0] https://en.wikipedia.org/wiki/Urban_revolution


> it was also a mess of intricate object ownership

Not much has changed, though, it still is. Just with a lot more bells and whistles around it


Much has changed for me since I used smart pointers where possible - which is the vast majority of the time. I am currently telling somebody you can't change a QString to a C string even though the C string probably won't overflow in that use. I have changed.


Smart pointers existed long before C++11. std::auto_ptr was a mistake, but it wasn't the only option


Smart pointers somewhat existed. Without move they were vastly less powerful. (You could have a generic shared pointer without move, but unique pointer has useful properties that you cannot get without move) Non-generic smart pointers - RAII - was very common but that was implemented separately for everything. Having to figure out how to deal with copy was a problem (though many times you disabled it and then passed a reference or a raw pointer to the object - a poor mans move which sometimes was good enough but often was annoying).

More importantly, before C++11 every library I worked with had their own incompatible way of managing memory. None of them used smart pointers in the API, it was always raw pointers (or references where possible but often not possible) and their own documented ownership rules. Any single library was simple enough to follow the rules (hint we got it wrong often), but the combination was very complex and sometimes impossible to combine the two different rules.

C++11 changed how most people manage memory. You could get the same effect without, but it was both more complex, and nobody agreed on the same rules.


Most kanji are a combination of several smaller parts called "radicals" in English. If you look at these two kanji through this lens, you will see that it's actually a very simple mistake, one existing radical is replaced by another existing radical. It is very easy to imagine software that was working exactly like that: interpreting kanji as a combination of radicals rather than individual unrelated symbols


This reminds me of the pregnant man emoji [0] but it turns out they decided to handle that in an unusual way [1] so not really.

[0] https://emojipedia.org/pregnant-man

[1] https://www.reddit.com/r/technology/comments/u7x3l9/comment/...


> indefinitely

Which, in practical terms, means "while I or my investors have money". These guys have 70 years worth of data, can you guarantee to keep it for another 70? The real answer to these kinds of problems is managing the data yourself


There's a difference between an archive and a backup it's true. If this really is intended to be archival they need to come up with a plan with the Library of Congress, the US Archives, or a similar institution. There are archivists in the world and they should come up with a plan for this that's written and will outlast all the people in the room.


Not certain how well LOCKSS has done over time as Internet Archive seems to get all the press, but it seemed to be a solid concept with some level of implmentation:

Taking its name (Lots of Copies Keeps Stuff Safe) from the idea that a file is more likely to survive if it has multiple copies stored in multiple places, LOCKSS software allows libraries to create preserved digital collections out of materials that would otherwise be accessible only through a licensed academic subscription. LOCKSS has agreements with academic publishers to permit libraries to store local copies of content that is usually only accessible through web-based subscriptions, enabling post-cancellation content access.

https://coptr.digipres.org/index.php/LOCKSS_(Lots_of_Copies_...


LOCKSS is a technology and I could imagine it being part of a plan - but archivists still need to consider what entity owns the data and has rights to give access to it, what jurisdiction governs the data, how to transfer ownership/rights, which combination of tools should be used to achieve the goals, and also what goal there is for the data.


At present (especially for PBS), it would be wise to use an archive service that receives zero U.S. federal dollars and is not subject to the executive branch’s efforts to rewrite history to fit their preferred narrative.


I'm surprised libraries haven't taken a similar route to universities and store local data and backups for neighboring libraries.

Libraries were the archives for newspapers and local public information.


I doubt many libraries have the budget for it. Libraries aren't a popular service and are perennial targets for conservative "cost cutting."


rsync.net is a special exception. Maybe the most reliable and trustworthy service money can buy.


I'm thinking of ways to do that. I think maybe partnering with long lived institutions like universities or national libraries?


There is a different between a conflict and a war. Humans are uniquely violent and cruel to each other, there is nothing even close in the animal world


You should learn about chimpanzee wars and how dolphins treat tortoises, and about the enslaving ants


> how dolphins treat tortoises

Do you mean porpoises?

Dolphins are not known for mistreating tortoises but porpoises.


Yes, I messed that up based on phonetic recall I think. Thanks for correcting


The famous C dilemma: we want to be as close to the machine as possible, but don't want to change anything when the machine changes


Because contrary to urban myths, C is a normal high level language like everything else.

The Assembly like abilities have been growing as language extensions in specific compilers, not as part of ISO C.

Going back to K&R C, inline Assembly or intrisics were not even available, all of that required using the Assembler directly.


> Because contrary to urban myths, C is a normal high level language like everything else.

It's a myth that this is a myth.

Have you ever worked with newbies learning C?

These students split pretty hard into two camps (of course there are oddball exceptions): those who knew assembly and find C easy, and those who didn't and struggle with pointers until they finally get it (some, never do).

Of the mainstream languages, C is the only one where understanding and dealing with direct memory access is a fundamental requirement if you're going to get anything done.

The myth argument is that C code doesn't directly translate into the execution flow on the CPU. No, of course it doesn't. That's not the point.

What people mean when they say C is lower level than most mainstream languages is because it forces you to deal with details most other languages paper over.

Yes, multiple languages have some way of achieving this kind of memory access, but except from C, it is considered an esoteric edge case that mostly nobody needs.


I might have learned all this too long ago and lost touch with how it's like to learn this, but: how is learning about using pointers in C different from using object references and array indices in python/js/java?


> how is learning about using pointers in C different from using object references and array indices in python/js/java?

That's exactly what trips up people coming from higher level languages!

If you think of it in terms of objects and algorithms (linked lists etc) it is basically the same thing, so it feels like the same thing until things break in ways that make no sense (to people coming from high level languages).

To someone coming from assembly, you just tell them a pointer is like a register holding a memory address and everything is immediately obvious.

(I came to C from assembly so that was my experience)

But people coming from high level languages expect the semantics that a pointer is somehow bound to an object or data structure, which it can pretend to be, but ultimately it's just a register holding a memory address. So it can point to the first byte of the memory space holding your object, or it can point to the middle of it or to any random spot in memory. Or you can reinterpret what structure you pretend it is pointing at just by recasting. And so on.


In C a pointer can point to any arbitrary offset within an object or array, to a local variable somewhere on the stack, to a static variable, to read-only memory, to the first(?) of an indeterminate number of characters (hopefully) terminated by ((char)0). To the first of a statically unknown number of variables located somewhere in memory, to a variable of indeterminate type (thanks to union), to I/O devices, and also to unallocated memory since there's no bounds checking.

A reference can only point to an object or an array on the heap. Array indexing is bounds-checked.

It seems obvious to me that these restrictions make references easier to reason about than C-style pointers, and therefore easier to learn.


>It seems obvious to me that these restrictions make references easier to reason about than C-style pointers, and therefore easier to learn.

I came to C from Assembly, so maybe I'm in a different camp, but references seem to me to be more difficult to reason about than pointers. Pointers just are, like math; references seem like a bunch of semi-arbitrary conventions.

Like the difference between writing SQL and using an ORM, which is supposed to be simpler but ends up being messier.


I imagine most of these examples (besides strings) isn't something you learn in the beginning and when e.g. doing operations on linked lists you're pointing to either allocated structs or null.


You tend to learn it early not by choice, but because the student makes some operation on the pointer and suddenly all they get are core dumps or (seemingly) bizarrely corrupted data and they have to confront what's going on early in the learning process.


Not every high-level language gives you byte-level access to the representation of memory objects.

But it is also wrong to reduce a language to what is in the spec.


Many do, contrary to what many C advocates talk about.

Apparently reducing the language to what is in the spec is only a thing when talking about C and to some extent C++.

When other languages have compiler specific extensions beyond the spec, it is a failure in their design.

Yet when C and C++ devs have to reach out to compiler specific extensions, it is not a design failure like it is pointed out to others, rather an advantage.

It is also wrong to not apply the same measure when it doesn't suit the message.


You comment this almost everyone it comes up. The hardware also isn’t x86! That’s an abstraction too.

The point is in C you have greater control of execution and resources, not that it matches the hardware exactly. It’s a spectrum and C is closer on that spectrum than JavaScript.


Because just like your comment proves the point, many think only C can do this.

So I keep re-educating folks that isn't the case.

Every thread has different people reading it, so there is always a first time for many of them.


You are again misreading even the most clearly put statement. Compared to e.g. Javascript, C is "closer" to the hardware, gives you "more control" of it. It would be completely ridiculous to deny this fact.

And if you move to e.g. C# / Java or similar, if you squint, and you try to be a smart-arse, then you could deny that C is closer to the hardware than C#, because C# probably has everything you need to control it, to the same degree that C allows you to. But if you work in these languages for a while, and look at the code that you ended up producing, then again you will absolutely find that it would be ridiculous to not admit that C gives you better control.

And you could even extend this to Rust, because the language encourages you to use high-level prefabricated components. It discourages you from doing low-level things, at least a little bit I think (I'm not a Rust user).

I think what you are doing all the time, is you are being a smart-arse, nothing else. What interesting low-level performant things have you actually programmed lately?


> But if you work in these languages for a while, and look at the code that you ended up producing, then again you will absolutely find that it would be ridiculous to not admit that C gives you better control.

I disagree somewhat. C gives you better control, and you have to accept that gift to get anything done. The likes of (modern) C# give you better control, but you can reject the gift if you want, and program in higher abstractions. You can also accept it in some places and reject it in others.

With C, you can reject the control, too, but then, you have to use third party libraries (or write them yourselves), and using those, your code looks less nice because it cannot escape C’s syntax (yes, macros help a bit there, but having real syntax beats it)


Mind you, the "you can use this other way as you see fit" idea often isn't practical (like combining GC'ed and non-GC'ed parts). You generally want a whole codebase to be structured according to shared idioms. Otherwise the interfacing cost becomes too high.

I have doubts that you can program easily in a C-style way in C# without adding lots of annotations everywhere in many places. But don't know, maybe I'm wrong, I did a search for a simple C-style arena allocator in C#, and it looked acceptable, it was quite close. The most annoying thing was maybe keyword boilerplate.


Smart-arse is comparing C versus JavaScript, instead of C vs C++, for example.

And then coming with such lengthy ad hominem.

Let make a fun exercise for the audience, given your performance remark.

Paste a random C code that I should replicate in whatever language I feel like.

There is one rule.

If the sample code is pure ISO C, then I will only use what is in the standard of whatever language I pick up.

If the sample code makes use of single language extension not part of ISO C, then I will have the freedom to also pick whatever language extensions I feel like.


So do you want to "rewrite" some C code in C++ to think you made a point? I think you should do C# or Java.

What about you do xxHash? Should be quite basic, not a lot of complicated structures. https://github.com/Cyan4973/xxHash/blob/dev/xxhash.h

Or what about you do an audio or video codec? Or an operating system?

Not going to paste any of my own code, because any non-trivial stuff is hundreds to thousands of lines. But one more example (that I recently did myself): Create a block allocator (power of two blocks) with bookkeeping in shadow memory (administered in individually committed zones representing virtual memory regions of 64 MB (2^26)). Any used memory has bookkeeping support for being sub-allocated at any and all levels up from 64 KB (2^16) to 64 MB (2^26), and even higher (by joining committed regions). Individual blocks are collected (using intrinsic linking, because no memory allocation) in a hierarchy of pools of same-sized chunks that have the same parent, and can be recursively sub-allocated on any smaller chosen power-of-2 level, and finally be consumed in linear fashion (arenas). Blocks are pooled with a moderate retain policy (watermark system) to allow subsystems to almost completely avoid any system calls and avoid inter-thread synchronisation. The memory overhead must be below 1% even though it's totally flexible (as said has metadata for all levels from 64 KB up).

The bookkeeping should function on 32-bit systems (small virtual space, occupancy range from megabytes to 3 GB) as well 64-bit systems (2^48-2^57 bytes of virtual address space, occupancy range from megabytes to hundreds of gigabytes) with reasonable overhead compared to actual usage.

This requires intrusively linked lists, occupancy bitmasks, bit-counting and bit-prefix counting, OS syscall access (virtual memory), pointer arithmetic (alignment needed to address shadow bookkeeping memory) and thread synchronisation. The reference code is >> 95% pure ISO C++11 (could be C99 with few changes), with a little platform code glued in. It works on Windows but it could be ported to Linux in a few hours. It supports a mostly-immediate-mode GUI with hundreds of thousands (maybe millions?) of small variable-sized allocations per second. Allocation has almost completely disappeared from the CPU profile, well below 1% of CPU usage.


I said any systems programming language, and stated the rules, so I gather you don't want to play this game after all.

> Or what about you do an audio or video codec? Or an operating system?

There are already plenty of examples out there, Claude can probably help you there regarding history of such products not written in C, or where C required help from Assembly code.

You can start by researching IBM i, z/OS, OS 2200, Xerox Alto, DirectX and Metal (C++ for the most part, and Objective-C++ on the 2nd)

> This requires intrusively linked lists,....

And the C99 version is impossible to be written in Ada95 because?


Who uses Ada95 or whatever? You are fighting strawmans, nobody has made the claims you imply. My personal opinion is just that low-level access is essential to make interesting and performant programs. Object-type fluff doesn't help with that, it's getting in the way.


> Smart-arse is comparing C versus JavaScript, instead of C vs C++, for example.

Using C++ as your other comparison point when arguing that C isn't low level is by far the most smartass idea in this thread.


Not at all, because for C heads, C++ can't do what C does, for whatever imaginary reasons.


I challenge you to find one random person making that claim and to present it with a straight face. What kind of ghosts are you fighting?


Yeah, I see plenty of people complain that C++ can't be simple because devs will keep reaching into the cookie jar, but that's not the language being unable to do something C can.

The only complaint I see about C++ not being capable is the correct observation that more platforms have C compilers than C++.

Either way, C++ spans a big range that goes just as low level as C. Even if these complaints are real they don't make it a reasonable comparison point for the "C is actually high level" argument.


Requesting a block of system memory, by address, and writing to it.

This is common with C, when interfacing with hardware.


Define how you want to write to that system memory without OS syscall.

What exact C code did you had in mind?

So that the counter example is close enough to it in exposing the same semantics.


> If the sample code makes use of single language extension not part of ISO C

What are you even arguing right now? (Btw -ansi compiler flag)

> Smart-arse is comparing C versus JavaScript

I chose JavaScript to make the idea of a spectrum clearer using extremes. I can do C++ if you like. The machine doesn’t care about destructors, move, concepts, initializer lists, virtual methods, launder, or inheritance. You are programming against an abstract model further divorced from how x86 CPUs work.


That many features are not ISO, and any language can have extensions just like C, nothing special there.

To me choosing JavaScript as example against C, feels like the Tiger Beetle guy that initially chose JavaScript and then went to Zig because JavaScript did not deliver, go figure.

So many systems languages to chose from since 1958.


This responds to nothing in my comment.


_You_ do that. All the time. And then you fight these strawmans.


And you reply to that all the time with the C bias as well, oh well.


"When other languages have compiler specific extensions beyond the spec, it is a failure in their design."

This one of the failures of Linus T. with the linux kernel: he was not able to keep the assembly source code with plain and simple C code you can compile with a small and alternative C compiler (same failure for the glibc devs I think).

I don't blame him, he is already keeping the linux ABI stable, and pulling that off is something.


Many other languages only have one compiler available to start with.

Each additional compiler supported by a project means variance in functionality and thus additional work for the project. That work could make the codebase more robust. Or it could be a ton of useless work. Or anything in between. Depends on the context of the project.


> assembly source code with plain and simple C code you can compile with a small and alternative C compiler

Which part of that big clause is the part that failed? Because I thought you could still compile Linux with TCC.


As far as I know, that was for x86(32bits) linux, that decades ago.

With those assembly source files (which do not abuse any pre-processor) and plain and simple C, I could build a modern x86_64 linux kernel with cproc/qbe (which gets 70% of gcc speed in my CPU intensive benchmarks... for a few % of gcc code and in plain and simple C, not brain damaged c++).

But I kind of don't mind since the future is assembly coding on non-IP-locked standard like RISC-V, and the main issue for that future is the abuse of pre-processors (ffmpeg was bitten by it) or code generators which would not be written in assembly themselves (or with a simple high level language with an assembly written interpreter, asmpython?).


I had checked that the project was touched more recently but apparently the kernel version wasn't updated at all. So yes, decades ago, oh well.


Indeed, Linus T. is not superman, he cannot preserve linux of all the danger around.


Lot of stawman arguments.


Wouldn't be a authentic pjmlp comment unless they shit on C/C++ and/or praise Java/.NET with a bunch of straw-men :)


How wrong you are, C++ isn't in the same league as C, Microsoft was right not wanting to keep updating their C support.

It was already outdated by the time Borland released Turbo C++ 1.0 for MS-DOS, and only got new wind thanks to GNU FOSS and their manifest to prefer C as the main compiled language for GNU projects.

Everywhere else outside UNIX, was going with a mix of C++ for OS frameworks, Apple, Microsoft, IBM, Be, Nokia, Epoch,....

Naturally given the option, between C, C++ and something else I might prefer that something else, however I managed a few interesting positions exactly due to my C++ skills, and interests.

So don't mix my preferences for C and C++ on the same basket.


Wouldn't trade it for anything <3 Enjoy your Tuesday mate :)

> So don't mix my preferences for C and C++ on the same basket.

That mistake is mine indeed, I'll remember. Thanks, and I hope "no harm meant" was implicit :)


> Wouldn't be a authentic pjmlp comment unless...

> and I hope "no harm meant" was implicit :)

Ad hominen then an apology, mixed signals here or I'm missing something. Maybe sarcasm?


Yeah, original/parent comment I wrote with a twinkle in my eye (hard to communicate though), hoping that the smiley at the end conveyed it, but I might have replaced ; with : mistakenly.

I think many of us throughout the years been reading pjmlp's comments which fits a certain "theme". I don't mind though, it's just text after all, but was hard to keep myself from entering the meta-conversation when the opportunity just sat there. I still don't mean no harm by it, we all have our less agreeable ways of writing our comments, I'm surely guilty of it in some way too.


I understand now this is old gripe, and we are all to blame for this guilty pleasure I think :)


> Ad hominen then an apology, mixed signals here or I'm missing something. Maybe sarcasm?

You can express annoyance at someone's pattern of behavior without it being personal. embedding-shape isn't the only person annoyed by pjmlp's repeated disdain and snark towards people who use C (or Zig or WebAssembly or Rust or...).


I didn't see snark prior to being provoked, but this seems like a discussion with history beyond this scope so I think I'd better sit this out


Usually I reply in the same tone as I get talked with, I have no qualms with touchy feeling culture of modern times.


> Usually I reply in the same tone as I get talked with

No, you're usually the initiator. Usually it's with some off-hand quip about how C programmers don't understand C, or how the people designing WebAssembly are ignorant of COM or the JVM, or how Zig is just Modula-2, etc.

Most threads you participate in aren't filled with snark until you enter them.


You can chose no to reply, you do reply, I answer in the appropriate tone.


That explains the escalations


Really?! That is how many in C circles, including your regular comments to my comments happen to be like.

Two measures two weights, in C versus other systems languages.


Maybe provide a concrete example instead of making vague accusations. Or rather, please not, it is not a useful discourse. A productive response to my comment would be an insightful explanation of how byte-level access to memory objects is done in other languages.


> explanation of how byte-level access to memory objects is done in other languages.

I'm not pjmlp but I can explain this for the case of Rust, where this works a bit like C but with a few interesting differences.

Mainly, in Rust there is not a concept of a "memory object" per se in the runtime semantics. Memory is made of allocations and allocations are made of bytes. Unlike C, bytes are guaranteed to be 8 bits in size. Every byte of memory can hold integer values (0x00 to 0xff), pieces of a pointer or be uninitialized. That means there is nothing like strict aliasing, and therefore no need to have special rules for byte-level access. You can alias any type as any other type, so long as you avoid all the other sources of UB (out-of-bounds access, uninitialized memory access etc.).

The way to practically access this is much the same as in C. You can do things like cast pointers between different types and project a pointer to a struct to a pointer to one of its fields. It should be noted that, unlike with major C implementations, structs do not have a stable, well-defined layout, so if you do manual pointer math you need to put #[repr(C)] on the struct to get C layout rules (which might still yield platform-dependent field offsets, e.g. size_t is not the same size everywhere).

Note also that these are the dynamic rules of Rust, you need to follow these when writing unsafe code to avoid UB. The static rules of safe Rust are much more restrictive and don't allow much at all. It is possible to write unsafe code that exposes safe abstractions for this, one example is the "bytemuck" crate. It provides macros that can parse a type definition to check certain properties (e.g. well-defined layout, no padding) and then provide you with safe functions for byte-level access. Since there is no strict aliasing, for certain types you can also get safe functions for access at other granularities. For example:

  #[repr(C)] struct Foo {
    x: u32,
    y: u16,
    z: u16
  }
can be safely accessed as an array of u32 values (uint32_t in C), but

  #[repr(C)] struct Bar {
    x1: u16,
    x2: u16,
    y: u16,
    z: u16
  }
can not, for alignment reasons.


Yes, Rust copied many good ideas from C (and added many new).

BTW: If you use character-pointers, you also do not need to worry about strict-aliasing in C.


Easy accessible in a NEWP, Mesa, PL/I, Modula-2 or Ada manual, on how to map structs into byte arrays.

Or for something more modern either D or C++ will do.

Examples omitted on request.


> That is how many in C circles

Being able to find someone who's made the argument you're rebutting doesn't make it not a straw man. What matters is whether the person you're arguing with is making the argument.

Specifically this:

> When other languages have compiler specific extensions beyond the spec, it is a failure in their design.

Is not a point I've seen anyone here make.


> Not every high-level language gives you byte-level access to the representation of memory objects.

Any code that ventures anywhere near that territory is 99% Undefined Behavior. It's almost impossible to write proper C/C++ code that isn't UB while touching byte-level representations.


This is certainly not true. Accessing bytes of objects is well-defined in C.


Just look at this: https://blog.habets.se/2026/05/Everything-in-C-is-undefined-...

This is undefined behavior!

const int* magic_intp = (const int*)bytes;

Heck even something trivial like this is UB:

bool bar(char ch) { return isxdigit(ch); }

The only safe thing to do is memcpy, but that's super useless. As soon as you try to interpret or manipulate the byte-level data in any way, there are UB traps everywhere you go.


Yes, using an arbitrary type that is different from the one of the object is UB. But any access of a representation byte using a character pointer is well defined, not just memcpy and I would also not call memcpy useless.


I would argue that inline assembly, while not in the standard, is really just a convenience feature -- it is part of the standard to declare an extern reference to a function in the symbol table and jump to it, it just requires a separate ASM object to link alongside your C object. Inline assembly doesn't allow anything you can't do without it.


What does an external function have to do with the C supporting or not supporting ASM? The symbol is just a symbol from another object. That could be written in any language that follows the ABI (not that ASM has any enforcement of ABi to begin with). The symbol resolves to an address and nothing more.

Saying inline ASM is no different than a function call is like saying standard control structures are no different from function calls. I suppose from a Smalltalk perspective that could be true, but is that the mental model most programmers use?

I work on a system from the 90s with custom instructions. GNU-as was patched to understand the instructions. They’re used through macros that ultimately expand to inline ASM. Without this, you’d need function inlining, which may or may not be possible with a linked object (it certainly wasn’t standard in the 90s). So now a single instruction turns into stack management, a jump, more stack management and a return. At that point any benefit to a specialized instruction may be erased, or in the case I’m dealing with talking to external hardware becomes unreasonably expensive.


that's kind of not true. inline asm lets me refer to the register that the compiler placed a value in.

lets say I really want to use popcnt in my inner loop. with inline assembly I can just shove it in there. external linkage forces a function call overhead that can't be inlined, which obviates any benefit I might have had from using the specialized instruction.


You'd probably also be able to use an intrinsic to avoid the pain of inline asm and make it portable.


Intrinsics usually come after new instructions have existed long enough for the higher level pattern across several architectures to establish a common pattern. If specific hardware is being targeted you may need to use those instructions before intrinsics exist.


intrinsics are nicer in every way, assuming they exist. but some instructions are inherently non-portable. performance instruction like my popcnt example are good candidates since they can be implemented at varying costs on other architectures. but for systems programming there are control register and mode switch instructions that really aren't. some of those can be put into separate asm routines, but there are some that are poorly suited. segment long jumps on x86 are maybe an example. rdtsc is another one potentially.

its also true that when I unwrap my new spin with fancy new instructions its unlikely to have a robust set of instrinsics around them.

inline asm is a real mess, I always regret tussling with it, but its kind of pragmatically necessary if you're actually working at the metal in a high performance or embedded context unless you're doing the whole thing in assembly.


Inline assembly is inline. You're not following the platform ABI's calling convention here, you are choosing input registers, output registers, and trashed registers right there. Following the platform's ABI and carrying out the function call has a cost, merely picking registers does not.


It's not normal in any other language that constant-folding in the compiler has different behavior than running an expression on the machine.

C exists in a nether world of being neither assembly nor high-level language.

People only call it high level because in the 1970s, having blocks, loops, and functions was high level, compared to the SoTa machines available in the day, which were either programmed with assembler or some bespoke thing the manufacturer came up with.


There are high level systems languages starting with JOVIAL in 1958 for the SAGE radar system.

C only exists instead of the alternatives, because according to Dennis Ritchie himself it was more fun to create C than using something else, and I quote:

"Although we entertained occasional thoughts about implementing one of the major languages of the time like Fortran, PL/I, or Algol 68, such a project seemed hopelessly large for our resources: much simpler and smaller tools were called for. All these languages influenced our work, but it was more fun to do things on our own."

From https://www.nokia.com/bell-labs/about/dennis-m-ritchie/chist...


Quote does not support the claim that the only reason C exists was that it more fun


You read it your way, I read it my way.

"All these languages influenced our work, but it was more fun to do things on our own"


I never really thought much about this quote before now, although presumably I had read it…interesting how humble Dennis Richie was


That doesn't quite say what you claim. The choice was because the other languages were too large/complicated, not because of fun.


"...but it was more fun to do things on our own."


"..simpler and smaller.."


Unix team developed C partially to regain a bit of the state of the art that they were excluded to earlier, with added constraint of being very small machine so they couldn't just fit a state of the art language without making complex multi pass compiler - not in 32kB of RAM


But I assume that both on compiler and on machine, the evaluation is still conforming to the semantics of the C abstract machine?


may I ask specifically what aspects of C lead to examples of quasi low level status such as the one you gave? I'd hazard a guess the C abstract machine is defined in a particular manner differentiable from say the JVM?


It has pointers and pointer arithmetic. Pointing into the stack, allocating buffers on the stack (and the resulting decades of stack smashing attacks that came with it). Most languages don't have an underlying model of a flat memory that you can just randomly point at and write things; they have objects and data types and functions that aren't meant to be pointed at (and usually cannot).


It isn't actually that flat in the spec, though modern machines' address spaces are. So in a sense it is merely an accident of a specific implementation that you can smash stacks.


Yes, you are right in that programs are not supposed to point outside of allocated blocks into other regions, that's UB. As in, pointer arithmetic that computes pointers outside of (but not even accessing!) an allocated block is UB. Annoying, pointers can legally be put into integers, looked at (e.g. printed out as a hex value), and then reinterpreted back into pointers, so it more-or-less dictates flat addressing. E.g. it's basically not possible to make an implementation that would run most programs where pointers are unforgeable, relocatable things, because of this. All of this spec is post-hoc, so it's a nasty retcon job that papers over the old folk understanding of one flat address space that's more or less still there in every implementation.


Casting integers to pointers is implementation-defined as far as I know. Even if weren't, I'm not convinced that you have to interpret C's address space as flat just because it is finite or because pointers are representable as integers. In any case, machine's address spaces are flat (the physical memory mapped into them not so much), and working with real machines is what I'm interested in.


ah so other languages emulate harvard to a degree. I wonder if performance could improve by reimplementing a C like language based on a von neumann abstract machine inspired by something other than a PDP. thanks for your response


It's a similar distinction, but not really? Harvard is about separating code and data and C still does that with high reliability. Pointers and the stack and the important return addresses on the stack are all data. Strong barriers between different pieces of data are a different concern.


Well the title of this very post is about the ABI. The ABI provides some guarantees on what the compiler output will be. It guarantees that parameters will be read from certain registers and results will be written to other registers. Most languages do not offer such guarantees.


It really hasn't much to do with C (e.g. there is no such thing as a "C ABI", and especially no such thing as a "standardized C ABI" - not sure if that's even a hot-take anymore).

ABIs are defined by CPU and operating system vendors. Those ABIs usually happen to be quite 'C friendly', but that's not a requirement (for instance the AmigaOS ABI was primarily meant to be used from handwritten assembly code, and Amiga C compilers had to adapt to those ABI rules or they wouldn't be able to call into the operating system DLLs).


Yep, an ABI (function call convention) is computer language agnostic. It is a binary specification. And in real life, only a subset of it is actually used.

If they want to find something really obsolete, they better have a look at executable/dynamic lib file formats (PE+, ELF64). In other words, they better look at that first: I am using my own, which is beyond simple (a little RFC would suffice), no loader of any kind, basically userland syscalls. And I do embbed exes in an ELF64 capsule to run them transparently on linux systems (writting a internal linux exe loader would be copying ELF loading code while trashing 90% of its code). (hopefully in some not too far future, I'll try to build a mesa AMD vulkan driver for this very simple format and for that the main issue is.. c++ with its runtime, as always...).


No-one cares anymore about ancient computers or weird specialist systems of course, but don't neglect my important requirements by breaking compatibility with any the platforms I am relying on at any point in time. We also need all of the most aggressive optimisations that compiler writers can come up with—this is high-performance code, after all!—but we certainly don't have time to deal with any breaking changes that would force revisions to our big important codebases. Make sure we can realise significant performance gains with just a simple recompilation. But remember to keep everything straightforward and close to the machine: we really hate all that weird UB which it's so easy to trigger by making an obvious, reasonable assumption which turns out to be wrong for some inexplicable reason.


Except for the basic integer types. Change those as much as possible. Hell, CHAR_BIT=12 just to keep them on their toes.

Personal pet theory: C is portable as in "you can retarget the compiler to any machine" moreso than "your code will run on any machine".


> Personal pet theory

This is actually how c grew up. This is also one of the reasons why the spec is quite ambiguous in certain locations. C is made to be easily portable not a universal codebase for all platforms (though you can get quite close with some tricks like macros). Remember the spec allows C to run on a Unisys 1100/2200 just as well as on a pdp-11.

I may be to embedded for this but if you want your code to handle long long as int64_t use . I am of the opinion that you should always use fixed width types as portable types are a huge footgun and kind off redundant.

Especially when you start doing a little more complex things expecting them to work exactly the same, like 128bit values on a 64bit platform.


int was supposed to be the signed integer version of size_t. Meaning that it conforms to the native word size of the machine.

But then a lot of software assuming that int means 32 bit got written and even 64 bit ABIs have kept int as 32 bits.


I imagine there would also be some cache pressure increase if you inflated all of those ints to 64 bits.


so what they gonna do ??


Can we please stop with this nonsense? No matter where you live and which language you speak you never call the majority of places on Earth right. Can we just accept it and move on?


It is not non sense. I am spaniard myself and I did not understood what he was talking about until I saw the correction(is this a club name or something?).

If I want to talk about "Seattle" and use "Siadol" a lot of people are not going to understand.


"Saragossa" is an old and well-established spelling of that city's name in English and this is an English-speaking forum


A name is what something is called. For people it's rude to call them by a name they didn't choose but for non-persons that doesn't matter, if everybody else wants to call it "Siadol" then that is its name.


Every language has his own name for tons of places. In Spanish it's Zaragoza and in English "Saragossa". Ditto with Londres/London.


At least you learned something new today


Until we get any tangible proof of life outside Earth, there is no difference


There is likely simple basic life as advanced as bacteria around the universe

But high level life was likely a series of complex accidents that is not reproducible or would be radically different than us

One of my absolute favorite PBS Space Time on the subject

* https://www.youtube.com/watch?v=abvzkSJEhKk


> There is likely simple basic life as advanced as bacteria around the universe

What is the basis for this assertion?


single-cell "life" can be so simple that scientists can create it in a lab "SpudCell"

* https://www.science.org/content/article/lab-created-spudcell...

somewhere among 2 TRILLION planets in our galaxy there is a planet with enough atmosphere and magnetosphere to protect it from space radiation so there is likely bacteria

but complex life far more difficult and unlikely, very rare, as explained in the PBS Space Time I linked above, the "Cambrian Explosion"

* https://en.wikipedia.org/wiki/Cambrian_explosion

if there are viruses and fungi out there however, they could mutate eventually with enough permutations and outside stressors

that video explains the huge leap forward with DNA vs simple protein patterns


"SpudCell" already has 36 genes; the information encoded there basically cannot occur by random processes. There is still an enormous complexity gap between it and abiotic systems.

> somewhere among 2 TRILLION planets in our galaxy there is a planet with enough atmosphere and magnetosphere to protect it from space radiation so there is likely bacteria

I reject this conclusion; it certainly isn't justified by the links you provided.


you don't think there is even single-cell life anywhere else but Earth?

why would Earth be that incredibly unique?

it's even plausible Earth was accidentally seeded by panspermia (bacteria on comets)


>why would Earth be that incredibly unique?

I think the answer to the question is easy if we consider quantum mechanics. It says every possible random event manifests in some universe. This means that an event or combination of events, no matter how incredibly unique, manifests in some universe.

Imagine the very first cell. Imagine that all the particles of that cell coming into the exact spatial location by pure random chance. It is a chain of incredibly random events. But it does not matter. QM says that it manifests in some universe.

So, We are just in one such universe. Of course, there might be universes where this incredibly random event have manifested more than once. But since then number of such universes are minuscule when compared to the number of universes where it happened only once, there is an overwhelming chance that we, as one conscious species, finds ourselves in a universe where life originated only once.

In the same manner, there could be universes where an entire brain assembled itself purely randomly. But the number of such worlds are a small fraction of the worlds where a single cell formed, and followed the relatively simple procedure of natural selection and end up as beings who can ask such kinds of questions.


Sorry, when you make an assertion, you don't get to demand I justify questioning it. You need to explain why I should believe you.

Your reversal of burden of proof is a red flag that you don't have a good argument.

IMO, it is quite plausible that OoL is extremely unlikely and that our solar system is the only place where life occurs in the visible universe. Not proved, of course, but the possibility is by no means unreasonable.


wasn't demanding, just wanted to hear what your own logic was instead

but it's pointless to go any further I guess as it's getting outside science

the weak anthropic principle can't be falsified so it cannot be argued

I don't think we'll ever hear from "ET" but I do think it's perfectly plausible to find single-celled or simple bacteria elsewhere someday (ie. Europa, comet or asteroid)


If I were saying we were definitely rare or unique, you'd have an argument.

But I'm not doing that -- I'm saying it's a possibility that is consistent with evidence.

The claim that life is common is different. For that, you really need to present an argument that life being uncommon is ruled out.

In your last sentence there you've retreated from "life is common" to "it's plausible life is common". Sure (within the constraints of the Fermi Argument, but that has uncertainties.)


Actually I don't think there is life outside of Earth. I think we are truly alone in this universe.


Its an exciting time to be alive because as of recently we certainly can detect planetary atmosphere major components out to at least 700 or so light years.

https://en.wikipedia.org/wiki/WASP-39b

There are astronomers actively working on minor component, more biologically interesting spectrographs like chlorophyll rather than spectrograms of carbon dioxide. That'll be harder to detect and limited to shorter ranges.

At some point, probably very soon, like less than a decade, we'll be able to definitively state that we have atmospheric data in an onion layer shaped shell where we have unequivocable proof that out to X lightyears from Earth there's no planetary scale chlorophyll higher than a minimal level aka there's no earth-like plants on that planet. That shell will likely expand over time. Or, perhaps we will find a forested, or at least algae covered, planet, some light years away, which would be very interesting indeed.

The question is rapidly changing from a purely philosophical belief to scientific observation, like right now, in real time, in the 2020s. What a cool time to be alive!

This follows old, old stuff from radio astronomy along the lines of how far away could a 1960s radio telescope realistically detect life on earth. The answer IIRC was not very far LOL. But there's been a lot of progress in radio astronomy, etc.

With respect to fermi filters etc people need to pay attention to how far away the Earth can be detected using radio telescopes. That distance has imploded since the end of analog UHF TV broadcasts. We still broadcast absolute swill, in fact more than ever, but digital detection range is much lower than analog AM carrier detection range from analog TV. The Earth has, to some extent, recently gone radio-quiet, which is interesting because we are still here, in fact more of us than ever. So WRT fermi filters of not being able to detect civilizations, disappearance of 1950s/1960s signals does not necessarily imply disappearance of civilization. Another example, if any aliens are watching the high altitude freon contamination of our atmosphere they're likely really confused right about now.


I agree. The Fermi Argument, and the apparent rarity of K3 civilizations in other galaxies, is to me powerful evidence of the scarcity of life. At the least, this suggests SETI should focus on distant galaxies where the Fermi argument doesn't bite as much.


Vote. It's literally the best thing you can do, apart from going into politics yourself


Guidelines | FAQ | Lists | API | Security | DMCA | Apply to YC | Contact

Search: