Hacker Read top | best | new | newcomments | leaders | about | bookmarklet login

I don't think those namings are inconsistent. primitive types and abstract types are not structs, and it would be misleading to label them as such. structs and mutable structs on the other hand are.

So, using 'only struct' or 'only type' "consistently" would be more homogeneous, it would be, respectively, wrong and under-specific. I think it's good that the concepts of type and struct are separated like that.



sort by: page size:

> Structs/value types can be mutable, records are not.

Fair point about record fields not being reassignable (not the same as immutable for others reading this).

> And as far as I know, while records have a sane default equals defined, they are still identity objects in that they are passed by reference.

Well, sure. All non-primitives are passed by reference. That doesn't stop them from being referred to as value types.

But in light of your first point, I agree that choosing a totally new term probably makes sense.


I disagree with the "always typedef structs" part. Personally I often find it nicer to have the "struct" there as part of the name. Partly because people sometimes typedef a pointer to the underlying struct type, and that can cause some issues.

The part about the author's take on RAII is interesting, but it would really merit a separate post with code examples.


The naming convention isn't important. If the structs are from different versions of the library then you either have a type error (nominal types) or have to figure out the semantics of arbitrarily uninitialized fields.

I've had luck using single-element structs to distinguish between types of data when I'm throwing a lot of primitive types around. In my test with gcc, the generated code was identical to using the primitives directly, although the standard doesn't actually guarantee that and it's historically not been the case in some particular compilers (not sure which).

It certainly makes sense to use struct and class to indicate what the type's role is. It's just good to keep in mind to avoid the confusion when you find the struct that has only pure virtual functions as members.

> I'm continually surprised by how often people insist on putting struct definitions right in their header files, defeating the whole idea of type abstraction.

It also defeats the idea of easy struct embedding as is done for example in the Linux kernel. Different codebases, different needs.


That's something I like to use for structured types, especially when the name is long and I can't be bothered writing "struct something" again, but I don't do it for char or other simple types.

Of course, it doesn't work when you're doing things like OOP in C, where the type on the left is a "superclass", or using flexible array members and allocating more than just a header's worth.


Agreed. In the literal sense they are very much two keywords for the same concept, but culturally, a struct is POD and a class is not.

Personally I think the mistake was in making them the same. In Ides, a friend's LLVM-based PL (no contributions here, just some discussion and ideas), an instantiated 'struct' is a non-polymorphic object rather like in C#; this allows for more expressive code by logically attaching methods to the struct but without creating a vtable and breaking C compatibility.


> In both cases, the compiler supposedly looks up the name on the right to figure out which struct type you intended. So foo->bar if foo is an integer would do something like ((Foo)foo)->bar where Foo is a struct that contains a member named bar, and foo.bar would be like ((Foo)&foo)->bar. The text doesn’t say how ambiguity is resolved (i.e., if there are multiple structs that have a member with the given name).

This is because in pre-ANSI C the names of struct fields were not internal to their enclosing struct but global identifiers that simply represented a type and offset. There was no ambiguity because different structs could not have the same member names. As raimue pointed out this is why some *nix struct members are still prefixed with a namespace like st_ for struct stat.


I understand the preference for keeping the struct tag, but virtually no other language does this, with modern IDEs it's trivial to find out what the definition of a given type is, so the tag seems superfluous to me in practice.

The only thing I can think of is that you could have

    int mytype;
conflicting with

    typedef struct { ... } mytype;
By putting the "struct" in front you only potentially conflict with other struct definitions.

Is that the thinking or is it something else?


That's right. The reason for this is that it's a lot of boilerplate if you were to require listing every relevant Impl block as a superclass of your struct. I also, as a bonus, like enforcing a consistent class naming style.

That is not what I'm saying.

Example: You can have 2 struct types that each only contain an int with the same member name. They would [likely] have the same binary representation. You could then create 2 vector types specialized for each struct type. The code for both vectors would handle the data in the same way - but the compiler would view the vector types as _STRICTLY_ separate types.

I do not think this code would be uniquely shared - the compiler would generate code for both vector types.


(author here)

I think I read the order of a struct members is guaranteed. So ssolen and type should not overlap ?


Changing it would break existing code. In C, types "A" and "struct A" could have been defined as completely different types.

Most of the structural typing systems I've seen count the names of fields as part of the type, not just the types of the fields. So, those two structs would have incompatible types in such a system.

Cool, I like that. In some ways, it would be nice if there were a friendly alias for struct{} as part of the language, but I suppose it's hard to come up with a good general name for that.

“Hidden” from whom and how? “Same fields in beginning” doesn’t characterize multiple inheritance. “Tagged structs” are just one implementation strategy for one kind of polymorphism, and “tagged” and “struct” are themselves jargon. Using and knowing the precise terminology is important when communicating technical concepts.

By the way C++ standardized it? Yes, the only big difference is property accessors.

By convention? Nope. The term struct pretty much stands for a pure data construct. C++ attempted (and pretty much failed) to make this distinction. Some languages, like C#, did a much better job.

In the real world we are always urging to being consistent. While other languages do a pretty good job by enforcing it, on C++ this is more on your shoulders.

next

Legal | privacy