Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

spec: improvement for wording #18950

Closed
zigo101 opened this issue Feb 5, 2017 · 10 comments
Closed

spec: improvement for wording #18950

zigo101 opened this issue Feb 5, 2017 · 10 comments
Milestone

Comments

@zigo101
Copy link

zigo101 commented Feb 5, 2017

In the end of the spec, there is a line:

For a variable x of array type: unsafe.Alignof(x) is the same as unsafe.Alignof(x[0]), but at least 1.

But what about if the length of an array is zero? Then x[0] is illegal. So a better wording would be

For a variable x of array type: unsafe.Alignof(x) is the same as unsafe.Alignof(a value of the element type of x), but at least 1.

Or it is best to add an exception: unsafe.Alignof(zero length array) is always 1. But I found in the latest go, unsafe.Alignof(zero length array) is the same as unsafe.Alignof(a value of the element type of x) .

@ianlancetaylor ianlancetaylor added this to the Go1.9 milestone Feb 5, 2017
@ianlancetaylor
Copy link
Member

ianlancetaylor commented Feb 5, 2017

Perhaps we can simply say that the alignment of an array is the same as the alignment of the element type of the array.

@griesemer
Copy link
Contributor

griesemer commented Feb 7, 2017

This seems inconsistent. Why should an array behave differently than a struct with respect to alignment? If the array is empty, it's alignment could just as well be 1. Then an array (fields are indexed) and a struct (fields are named) behave the same with respect to alignment.

@minux
Copy link
Member

minux commented Feb 7, 2017 via email

@griesemer
Copy link
Contributor

@minux I respectfully disagree with your arguments. 1) There's nothing intuitive about it: An empty array has size 0. There's no reason to force alignment > 1 (see next paragraph). 2) The rules of the type system are independent of alignment and shouldn't be brought in for justification (we make those rules - alignment is forced upon us).

Alignment is not a "good onto itself" - it's there to either make direct memory access possible (if unaligned accesses trap), or make it faster. Alignment costs memory and adds complexity. If it were not necessary and if it wouldn't cost not to have it, we'd drop it in a heartbeat.

I'd buy the argument that it's simpler (in the spec and the compiler - no need to check for 0 length). But we could absolutely go the other way.

I like to see a good example for forced alignment via a _ [0]uint64 field.

@cznic
Copy link
Contributor

cznic commented Feb 7, 2017

@griesemer I always believed it's the case as @minux described. I'm probably mistaken, but I even think I saw it used in the Go repository. And I'm completely sure I used this to force alignment of C unions translated to Go structs. It even serves as a nice documentation, for example:

type foo struct {
        _ [0]struct{ // some union
                field1 T1
                field2 T2
                ...
        }
        Union [xx]byte
}

@griesemer
Copy link
Contributor

@cznic I'm not disputing that it's implemented this way, or that the alignment trick is used somewhere (any oddity of a language will be used sooner or later...). My comment was primarily addressing the justification (it's intuitive, or similar what the type system does).

The justification (if any) is that it was implemented this way early on, probably because it was simplest (perhaps with or without the alignment trick in mind).

But thanks for the example.

(I'm a bit sensitive to alignment and related sizing decisions because I don't always agree with the current implementation. See e.g. #14909. I'm painfully aware that we cannot change things.)

@cznic
Copy link
Contributor

cznic commented Feb 7, 2017

I agree that alignment may cost extra memory and it thus should not be forced unless necessary. I think the interesting question is: How to explicitly force alignment in cases like above? How does CGO solve this problem?

@minux
Copy link
Member

minux commented Feb 7, 2017 via email

@gopherbot
Copy link
Contributor

CL https://golang.org/cl/36481 mentions this issue.

@rsc
Copy link
Contributor

rsc commented Feb 7, 2017

It seems to me that making [1]T and [0]T have different alignments is more complex than leaving them the same. I'd like to leave them the same instead of optimizing (aka special-casing) [0]T. The pending CL seems to do just that - not carve out any special case for [0]T - which is great.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

7 participants