Hacker Newsnew | past | comments | ask | show | jobs | submit | arjvik's commentslogin

Why can't there be a standard defined for bitfields in future C releases? This is a long-discussed drawback of a feature that I really really want to be able to use in production code.

There is, but it's part of the platform ABI and not the C language standard. The latter specifies syntax and behavior, the former is what's concerned with interoperability details like memory layout.

I happen to have a copy of AAPCS64 in front of me, and you can find the specification of bit packing in section 10.1.8. The sysv ABI for x86/x86_64 has its own wording (but I'm pretty sure is compatible). MSVC does something else I believe, etc...


There is. I'm not sure when it was added, but looking at https://www.open-std.org/jtc1/sc22/wg14/www/docs/n3220.pdf, page 106, note 13

> An implementation may allocate any addressable storage unit large enough to hold a bit-field. If enough space remains, a bit-field that immediately follows another bit-field in a structure shall be packed into adjacent bits of the same unit. If insufficient space remains, whether a bit-field that does not fit is put into the next unit or overlaps adjacent units is implementation-defined. The order of allocation of bit-fields within a unit (high-order to low-order or low-order to high-order) is implementation-defined. The alignment of the addressable storage unit is unspecified.

In practice, I've been using this feature for ages (along with __attribute__((packed))). There comes a point where you can start depending on compiler specific features instead of relying solely on the standard.


The portion you quoted derives word-for-word from the original ANSI standard (C89/C90): https://port70.net/~nsz/c/c89/c89-draft.html#3.5.2.1

Can this be standardized? It seems it would have accommodate the most limited architecture, in terms of memory access, probably making it practically useless. Seems best left to the compiler.

The quoted text is from the C standard. The poplar wisdom is that anything goes wrt bit-fields, but it's an exaggeration.

The original (?) DNS library used bit-fields to read and write the packet header status and flags fields, and that original code is still used today: https://github.com/openbsd/src/blob/master/include/arpa/name... It does rely on implementation-defined behavior--it swaps the order of fields based on whether the machine is little-, big-, or middle-endian--but even that behavior has remained remarkably consistent, at least on Unix ABIs.

I think the wisdom comes from dealing with niche compilers, especially from years ago, where bit-fields were one of the areas where standard adherence was less consistent; and in embedded and kernel contexts, where the implementation-defined and (implicit) undefined behavior, such as wrt atomicity or the intersection of bit-fields and (extension) packed pragmas, counseled against any usage of bit-fields.


I've been working on an open source library that, while it doesn't solve bitfields, can provide convenient ergonomic access to bit-granular types:

https://github.com/PeterCDMcLean/BitLib

You can inherit from bit_array and create a pseudo bitfield:

  class mybits_t : bit::bit_array<17> {
    public:
      // slice a 1 bit sized field
      // returns a proxy reference to the single bit
      auto field1() {
        return (*this)(0, 1);
      }

      // slice a 3 bit sized field 
      // returns a proxy reference to the 3 bits
      auto field2() {
        return (*this)(1, 4);
      } 
  };
  mybits_t mybits(7);
  assert(mybits.field1() == 1);
  mybits.field1() = 0;
  assert(static_cast<int>(mybits) == 6); //no implicit cast to integers, but explicit supported

There is minimal overhead depending on how aggressively the compiler inlines or optimizes*


different/more than std::bitset<SIZE> ?

Only similar by a little bit. Bitset misses the mark in so many ways.

bit_array can be compile time storage (ala bitset) or dynamic at construction time. There is also bit_vector which is entirely dynamic

Critically though, is that the type/library is built on a proxy iterator/pointer that lets you do certain things with STL or the bit algorithms that you cannot otherwise do with bitset.

But back to the bitfields idea. The bit array backing storage is configurable through templates so you will be able to know for certain exactly how much stack or heap your type will take up


who currently has control over the package on PyPI? wondering how it was compromised

New maintainers never bothered to change the range.. History num2words is based on an old library, pynum2word, created by Taro Ogawa in 2003. Unfortunately, the library stopped being maintained and the author can't be reached. There was another developer, Marius Grigaitis, who in 2011 added Lithuanian support, but didn't take over maintenance of the project.

I am thus basing myself on Marius Grigaitis' improvements and re-publishing pynum2word as num2words.

Virgil Dupras, Savoir-faire Linux


I have no idea, it hasn't been me for years.

Sucks if you drive a car

Doesn't VGA use DE-15?

Edit: I was wrong, it is DE-15 connector. They squeeze 15 smaller pins into 9 pin housing.

Made my day!

Is there a way to reward and incentivize improving human well being?

Perhaps a society where all income comes from the government in proportion to how much one improves the overall well being of society?

(Yes, it's difficult to measure this objectively, and even harder to agree on what the priorities for societal well being are)


Germany has a different structure for company ownership than the USA. Members representing relevant stakeholders (employees, the community, environment, etc.) must be present on the board and advocate for their interests.


UBI would go a long ways to enforcing democracy. Money talks, so just give people money. Everything else is too abstract. We can't seem to encode justice into law but at least if everyone got UBI it would be harder to oppress poor people

(half serious)


It’s not difficult, it’s impossible under freedom of religion and just independent thought generally.

One person’s “well being” might be measured by how many wives and children you have. Another’s might be education level and physical fitness. Another’s could be financial independence.

These all clash with each other in fundamentally incompatible ways.


I figured out how return-as-a-value made sense only upon realizing that in the following code,

    fn funny(){
        fn f(_x: ()){}
        f(return);
    }
f() is never called because funny() returns before it gets called.

The reason you want return to be coercible to any type is so that you can write something like

    let x: i32 = if y {
        4
    } else {
        return; // type ! coerced into i32
    }
And you pick the return value of ! because return never actually produces a value that is propagated on at runtime, it immediately exits the function.

(Note this all works even with returning a value)


Where's the 14%? Looks like their final kernels show a 0.14% improvement of Mojo over the equivalent CUDA kernel?


It looks because it does.

>(2771.35/2775.49 - 1) * 100 = -.14916285052369131300

Flagged.


Updated the title to the original. I did base the numbers on

"This kernel archives 1437.55 GB/s compared to the 1251.76 GB/s we get in CUDA" (14.8%) which is still impressive


Came here to present my strategy for solving it in two tries, and realized it was far more complicated! (started with 00011)



Consider applying for YC's Fall 2025 batch! Applications are open till Aug 4

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

Search: