Issue 15692 - Allow struct member initializer everywhere
Summary: Allow struct member initializer everywhere
Status: RESOLVED FIXED
Alias: None
Product: D
Classification: Unclassified
Component: dmd (show other issues)
Version: D2
Hardware: All All
: P4 enhancement
Assignee: No Owner
URL:
Keywords:
: 19237 20173 (view as issue list)
Depends on:
Blocks:
 
Reported: 2016-02-16 13:20 UTC by Jacob Carlborg
Modified: 2023-01-31 11:02 UTC (History)
6 users (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this issue.
Description Jacob Carlborg 2016-02-16 13:20:10 UTC
Currently it's only legal to use struct member initializer when declaring a variable:

struct Foo { int a; int b; }

void main()
{
    Foo foo = {
        a: 3,
        b: 4
    };
}

It would be a big improvement if something as the following was allowed:

Foo{ a: 3, b: 4 }

Then it would be possible to use the member initializer syntax in all places a regular struct initializer is supported. For example, together with "auto" and when calling functions:

auto foo = Foo{ a: 3, b: 4 };
bar(Foo{ a: 3, b: 4 });

An alternative syntax could be to use parentheses instead:

auto foo = Foo(a: 3, b: 4);
Comment 1 Alex Parrill 2016-04-06 01:44:08 UTC
My use case: Vulkan uses structs to pass large amounts of parameters around. My current code looks like this:

VkImageCreateInfo imgInfo = {
	imageType: VkImageType.VK_IMAGE_TYPE_2D,
	format: VkFormat.VK_FORMAT_R8G8B8A8_UNORM, // TODO: only allocate alpha if needed
	extent: image.size,
	mipLevels: image.mipLevels,
	arrayLayers: image.layers,
	samples: VkSampleCountFlagBits.VK_SAMPLE_COUNT_1_BIT,
	tiling: VkImageTiling.VK_IMAGE_TILING_LINEAR, //VK_IMAGE_TILING_OPTIMAL,
	usage: VkImageUsageFlagBits.VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VkImageUsageFlagBits.VK_IMAGE_USAGE_SAMPLED_BIT,
	sharingMode: VkSharingMode.VK_SHARING_MODE_EXCLUSIVE,
	initialLayout: VkImageLayout.VK_IMAGE_LAYOUT_PREINITIALIZED,
};
enforceVK(vkCreateImage(device, &imgInfo, null, &image.img));

It'd be really nice if it were possible to specify the struct inline with the creation call:

auto img = createImage(device, VkImageCreateInfo {
	imageType: VkImageType.VK_IMAGE_TYPE_2D,
	// ...
	initialLayout: VkImageLayout.VK_IMAGE_LAYOUT_PREINITIALIZED,
});

It'd also be very helpful for returning info structs from lamdas:

auto queueCreateInfo = priorities
	.enumerate
	.filter!(x => x[1].length > 0)
	.map!((x) {
		VkDeviceQueueCreateInfo info = {
			queueFamilyIndex: x[0],
			queueCount: cast(uint) x[1].length,
			pQueuePriorities: x[1].ptr,
		};
		return info;
	})
	.array;

You also basically have to use the the named field initialization syntax because each Vulkan info struct begins with a `sType` field and a `pNext` field, which at the moment should be a struct-specific constant and null that you don't really want to specify each time you create the struct.
Comment 2 Lionello Lunesu 2017-04-26 00:32:22 UTC
My 2c: this is more D-like,

auto foo = cast(Foo){ a: 3, b: 4 };
Comment 3 Jacob Carlborg 2017-04-26 18:47:35 UTC
(In reply to Lionello Lunesu from comment #2)
> My 2c: this is more D-like,
> 
> auto foo = cast(Foo){ a: 3, b: 4 };

I disagree, this looks weird.
Comment 4 Seb 2017-06-08 02:35:14 UTC
I just revived a DIP that deals with this topic: https://github.com/dlang/DIPs/pull/71

Help to polish it is welcome ;-)
Comment 5 basile-z 2019-12-12 20:18:43 UTC
*** Issue 19237 has been marked as a duplicate of this issue. ***
Comment 6 basile-z 2019-12-12 20:19:42 UTC
Another use case is with mixin expressions:

---
struct S
{
    int i;
}

void main()
{
    S s = mixin(`{1}`);
}
---
Comment 7 ZombineDev 2022-07-05 17:37:11 UTC
*** Issue 20173 has been marked as a duplicate of this issue. ***
Comment 8 RazvanN 2023-01-31 11:02:07 UTC
This has been implemented in https://github.com/dlang/dmd/pull/14776