3

Let's say, I have Swift struct named Foo

struct Foo
{
     var a,b,c : Float
     var d : Double
     init()
     {
        a = 0
        b = 0
        c = 0
        d = 0
     }
}

Swift sizeof(Foo) prints 24 bytes, 4 bytes for Float fields, 8 for Double and 4 bytes of padding on arm64.

So I consider, that there is no special Swift magic with structures alignment done, and we can freely pass pointers to it to internal C functions in order to use stuff like NEON and Metal, as long as built-in variables are unions, which currently can't be directly included into Swift

Somehow, when I try to get const void* to it (ConstUnsafePointer<()> in Swift) with

let a = Foo()
let b = &a

I get nasty compiler error on second expression

'Foo' is not convertible to '@lvalue inout $T1'

Did I miss something and this is done by design?

UPDATED PART

Martn R, thanks for answer! Still, entire situation is not very clear for me. My aim was to create convenient Math stuff wrapper, so I wanted to implement @infix methods like multiplication and hide all internal native stuff behind C. In case of Matrices, for example, that means, that we need to pull ampersand right from a = &b*&c expressions, because I didn't get from your answer and Docs if there is a way to bypass this and get raw point from memory in the scope of @infix method implementation.

Like this:

@infix public func *(l: Mat4, r: Mat4) -> Mat4
{
    var m = Mat4()
    _internalMat4Multiply(&l, &r, &m)
}

_internalMat4Multiply is void(void*, void*, void*) C-method, doing all the computations

1 Answer 1

7

There are two problems: You cannot take the address of a constant (defined with let), and you can pass the address of a variable only to function parameters. Assuming that your C function is

void myFunc(const void *data);

then this would work:

var a = Foo()
myFunc(&a)

However, instead of making assumptions about identical alignment in C and Swift, you should perhaps better define the structure in your C API:

struct Foo {
    float a;
    float b;
    float c;
    double d;
};

void myFunc(const struct Foo *data);

and use that from the Swift code:

var a = Foo(a: 0, b: 0, c: 0, d: 0)
myFunc(&a)
Sign up to request clarification or add additional context in comments.

2 Comments

Thanks for Answer, I would be pleased, if you could look at updated part and tell what you think
@ElijahIgny: Try declaring your function as @infix public func *(var l: Mat4, var r: Mat4) -> Mat4

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.