GNOME Bugzilla – Bug 609728
[PATCH] Fix dynamic array resize for out/ref arrays
Last modified: 2010-10-19 15:05:09 UTC
Created attachment 153619 [details] [review] Bug fix + test case When passing arrays as out/ref params, it is not possible to use construct "arr += element" in those methods. E.g. the following code compilation fails with error: ERROR:valaccodearraymodule.c:1349:vala_ccode_array_module_real_get_array_size_cexpression: code should not be reached [1] 23321 abort valac tests/methods/bug_xxx.vala The attached patch fixes this problem, by passing 'array_size' parameters to those functions, similarly to how array_length passing is done. == TEST CASE == void test(out int[] table, int dummy, ref long[] longtbl, string dummy2, string[] no_ref) { table = {10, 20, 30}; table += 1; table += 2; table += 3; longtbl += 10; longtbl += 11; longtbl += 12; } void test_simple_array() { stdout.puts(@"test_simple_array START \n"); int[] arr = {}; long[] arr2 = {100, 101}; string[] arr3 = {"one", "two"}; test(out arr, 23, ref arr2, "dummy", arr3); foreach (var i in arr) { stdout.puts(@"$i\n"); } foreach (var i in arr2) { stdout.puts(@"$i\n"); } } delegate void DoIt(int counter); void do_it(DoIt func) { stdout.puts(@"FIRST\n"); func(1); stdout.puts(@"SECOND\n"); func(2); stdout.puts(@"THIRD\n"); func(3); stdout.puts(@"DONE\n"); } void test_delegate() { int[] arr = {99, 98, 97, 96, 95}; // this should be replaced long[] arr2 = {100, 101, 102, 103}; // this should be added string[] arr3 = {"one", "two"}; test(out arr, 100, ref arr2, "dummy", arr3); do_it((i) => { stdout.puts(@"$i\n"); }); foreach (var i in arr) { stdout.puts(@"$i\n"); } foreach (var i in arr2) { stdout.puts(@"$i\n"); } } static void main() { test_simple_array(); test_delegate(); }
There is one thing I missed here. When I tried to compile vala source using valac with this patch, it fails on compiling compiler/valacompiler.vala: static int main (string[] args) { try { var opt_context = new OptionContext ("- Vala Compiler"); opt_context.set_help_enabled (true); opt_context.add_main_entries (options, null); opt_context.parse (ref args); <- PROBLEM ! The problem is that sometimes array can be passed as ref to C library which does not expect additional arr_size argument. I am not sure how to work around this, perhaps we would need some annotation (like no_array_size?) which can be added to vapi so that vala can skip generating the additional arr_size parameter in these cases?
The _size variable/field should be considered an implementation detail. We only use it for private fields and local variables to not influence the API. This means that it should also only be applied to parameters of internal/private methods. We also need to make sure that can use ref with _size on an array field that doesn't have _size (as is the case for public fields).
The compiler crash has been fixed in the meantime. Supporting += in more places is tracked in bug 616930. *** This bug has been marked as a duplicate of bug 616930 ***