On Tuesday, 18 February 2020 at 09:20:08 UTC, Andre Pany wrote:
Hi Petar,
Hi Andre, I'm happy to help :)
thank you very much for the explanation and the code sample.
Filling the az_span anonymous member was the tricky part,
I thought it would be not possible to do so, but you showed me
the trick.
I wouldn't call it a trick, I was using standard struct literal
initialization (the very syntax that DIP1031 proposes to
deprecate).
For example:
struct Inner { int x, y; }
struct Outer { Inner inner; }
// You can initialize Outer in various ways:
// 1)
auto o1 = Outer(Inner(1, 2));
// 2)
Outer o2 = { inner: Inner(1, 2) };
// 3)
Outer o3 = { Inner(1, 2) };
// 4)
Outer o4 = { inner: { x: 1, y: 2} };
// 5)
Outer o5 = { { x: 1, y: 2} };
// 6)
Outer o6;
o6.inner.x = 1;
o6.inner.y = 1;
For POD (plain old data) struct like that, all six variants are
equivalent (of course there more possible variations).
Since there's no `private` protection modifier in C, the only
thing C library authors can do is make it inconvenient to access
struct fields (by prefixing them with underscores), but they
can't really prevent it.
For example, without this syntax, in pure C you can initialize a
span like this:
char my_string[] = "Hey";
az_span span;
span._internal.ptr = my_string;
span._internal.length = sizeof(my_string) - 1;
span._internal.capacity = sizeof(my_string) - 1;
And with almost the same syntax you can do this in D:
string my_string = "Hey";
az_span span;
span._internal.ptr = cast(ubyte*)my_string.ptr; // note: I think
this should be safe, because of [1]
span._internal.length = my_string.length;
span._internal.capacity = my_string.length;
It's just that that author wanted to prevent accidental bugs by
pushing you to use the inline helper functions or macros (which
are technically not needed).
[1]:
https://github.com/Azure/azure-sdk-for-c/blob/25f8a0228e5f250c02e389f19d88c064c93959c1/sdk/core/core/inc/az_span.h#L22
I will do it like you have proposed but had also already created
a ticket for the Azure SDK developer:
https://github.com/Azure/azure-sdk-for-c/issues/359
There should be a more convenient way to fill a az_span
structure.
To be honest, I don't think the authors will agree to change
this, as putting inline functions in headers files is a pretty
common practice in both C and C++.
There are two benefits to that:
1) Potentially better performance, because the code is easier to
inline
2) It's possible to provide header-only libraries (not the case
here), that don't require build steps.
For reference, here is my dockerfile which does the DPP call
and linking:
Cool, I'll check it later!
``` dockerfile
FROM dlang2/ldc-ubuntu:1.20.0 as ldc
RUN apt-get install -y git libssl-dev uuid-dev
libcurl4-openssl-dev curl
RUN curl -OL
https://cmake.org/files/v3.12/cmake-3.12.4-Linux-x86_64.sh \
&& mkdir /opt/cmake \
&& sh /cmake-3.12.4-Linux-x86_64.sh --prefix=/opt/cmake
--skip-license \
&& ln -s /opt/cmake/bin/cmake /usr/local/bin/cmake
RUN git clone https://github.com/Azure/azure-sdk-for-c.git \
&& cd azure-sdk-for-c \
&& git submodule update --init --recursive
RUN cd azure-sdk-for-c \
&& mkdir build \
&& cd build \
&& cmake ../ \
&& make
RUN apt-get install -y clang-9 libclang-9-dev
RUN ln -s /usr/bin/clang-9 /usr/bin/clang
COPY az_storage_blobs.dpp /tmp/
RUN DFLAGS="-L=-L/usr/lib/llvm-9/lib/" dub run dpp -- --help
RUN DFLAGS="-L=-L/usr/lib/llvm-9/lib/" dub run dpp --
/tmp/az_storage_blobs.dpp \
--include-path /azure-sdk-for-c/sdk/core/core/inc \
--include-path /azure-sdk-for-c/sdk/core/core/internal \
--include-path /azure-sdk-for-c/sdk/storage/blobs/inc \
--include-path
/azure-sdk-for-c/sdk/transport_policies/curl/inc \
--preprocess-only
ADD blobs_client_example.d /tmp/blobs_client_example.d
RUN ldc2 /tmp/blobs_client_example.d /tmp/az_storage_blobs.d \
/azure-sdk-for-c/build/sdk/core/core/libaz_core.a \
/azure-sdk-for-c/build/sdk/storage/blobs/libaz_storage_blobs.a \
/azure-sdk-for-c/build/sdk/transport_policies/curl/libaz_curl.a
\
-of=/tmp/app
```
Kind regards
André
Cheers,
Petar