Skip to content

Translate socket functions in C mode#141

Merged
nunoplopes merged 3 commits into
Cpp2Rust:masterfrom
lucic71:socket
May 23, 2026
Merged

Translate socket functions in C mode#141
nunoplopes merged 3 commits into
Cpp2Rust:masterfrom
lucic71:socket

Conversation

@lucic71
Copy link
Copy Markdown
Contributor

@lucic71 lucic71 commented May 22, 2026

getsockname, and the rest of the socket functions that receive a struct sockaddr* (__SOCKADDR_ARG) parameter, are defined differently in C and C++:

int getsockname (int fd, __SOCKADDR_ARG addr, socklen_t *len)

#if defined __cplusplus
  #define __SOCKADDR_ARG		struct sockaddr *__restrict
#else
  typedef union {
    struct sockaddr *__restrict __sockaddr__;
    struct sockaddr_in *__restrict __sockaddr_in__;
  } __SOCKADDR_ARG __attribute__ ((__transparent_union__));
#endif

__transparent_union__ is an attribute that allows a function whose parameter has that union type can be called with any of the union's arm types directly, without a cast:

struct sockaddr_in in;
// this would normally generate an error because &in has type
// sockaddr_in* but the argument is declared sockaddr*
getsockname(fd, &in, len);

struct sockaddr_in6 in6;
getsockname(fd, &in6, len); // same tension between sockaddr_in6* and sockaddr_in*

__transparent_union is only available in C. In C++, an explicit cast is required.

In the Clang AST, the transparent union object is created through a CompoundLiteralExpression(InitListExpr(struct sockaddr_in *)). We convert the argument of CompoundLiteralExpression in order to get the correct rust code.

@nunoplopes nunoplopes merged commit a41a08e into Cpp2Rust:master May 23, 2026
9 checks passed
lucic71 added a commit to lucic71/cpp2rust that referenced this pull request May 23, 2026
`getsockname`, and the rest of the socket functions that receive a
`struct sockaddr*` (`__SOCKADDR_ARG`) parameter, are defined differently
in C and C++:

```c
int getsockname (int fd, __SOCKADDR_ARG addr, socklen_t *len)

#if defined __cplusplus
  #define __SOCKADDR_ARG		struct sockaddr *__restrict
#else
  typedef union {
    struct sockaddr *__restrict __sockaddr__;
    struct sockaddr_in *__restrict __sockaddr_in__;
  } __SOCKADDR_ARG __attribute__ ((__transparent_union__));
#endif
```

`__transparent_union__` is an attribute that allows a function whose
parameter has that union type can be called with any of the union's arm
types directly, without a cast:

```c
struct sockaddr_in in;
// this would normally generate an error because &in has type
// sockaddr_in* but the argument is declared sockaddr*
getsockname(fd, &in, len);

struct sockaddr_in6 in6;
getsockname(fd, &in6, len); // same tension between sockaddr_in6* and sockaddr_in*
```

`__transparent_union` is only available in C. In C++, an explicit cast
is required.

In the Clang AST, the transparent union object is created through a
`CompoundLiteralExpression(InitListExpr(struct sockaddr_in *))`. We
convert the argument of CompoundLiteralExpression in order to get the
correct rust code.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants