Community
Participate
Working Groups
Build Identifier: Juno, CDT 8.1 In the following code the editor does not correctly mark the write occurrences for the variables array and array2. int main( int argc, char **argv ) { int * array = new int[512]; int array2[100]; for (int i = 0; i < 512; ++i) { array[i] = i; // not marked as write occurrence array2[i] = i;// not marked as write occurrence } delete [] array; } Reproducible: Always
Patch pushed to Gerrit https://git.eclipse.org/r/#/c/12515/ This will handle the cases marked with NEW int main( int argc, char **argv ) { int * array = new int[512]; // write occurrence *array=5; // NEW: write occurrence &array2=3; // NEW: write occurrence int array2[100]; for (int i = 0; i < 512; ++i) { array[i] = i; // NEW: write occurrence array2[i] = i;// NEW: write occurrence } delete [] array; }
The clause "the value the variable points to is changed" needs clarification. Here are few examples that are not clear: What if the variable is a pointer to struct and one of the struct members is changed? Can the rule be applied recursively, like in ****a = 0; You can probably think of other non-obvious examples.
(In reply to comment #2) > The clause "the value the variable points to is changed" needs clarification. > > Here are few examples that are not clear: > > What if the variable is a pointer to struct and one of the struct members is > changed? > > Can the rule be applied recursively, like in ****a = 0; > > You can probably think of other non-obvious examples. I thought the examples listed in CPPMarkOccurrences would clarify this. struct A { void m(); int x; }; void test(A* ap) { ap->x = 1; // write access for ap ap->m(); // write access for ap (*ap).m(); // write access for ap int * ip; *ip = 1; // write access for ip ip[1] = 1; // write access for ip int b = ip[0]; // read access for ip int ipp[5][5]; ipp[1][2] = 1; // write access for ipp **ipp = 1; // write access for ipp You can define two sloppy rules: 1) replacing "." with "->" does not change read/write flags 2) indirection operator "*" and array subscripting "[]" do not change read/write flags
(In reply to comment #3) Do you agree that the rules in comment #3 lead to the following? struct A { int i; }; struct B { A* const a; }; const B* const b; b->a->p = 0; // Write access to both, 'b' and 'a'!
(In reply to comment #4) Sorry, I meant b->a->i = 0
I would agree. But this example is in principle identical to: struct C { int i; }; struct D { C const a; }; const D d; d.a.i = 0; The editor shows write occurrence for 'd' and 'a' (and 'i' of course). (I know that my example would not compile. But that is not the point here.) In your example b and a are both const with respect to the pointer. Therefore, there is from the semantics point of view only read access possible. But try a different look. This is what you see in the debuggers Variable View when you completely expand b: ->b const B * const 0x602010 ->a A * const 0x602030 i int 0 Then you will see that the write access flag is for the whole tree. If a member of the tree is changed all members above are marked as write occurrence.
(In reply to comment #6) > In your example b and a are both const with respect to the pointer. > Therefore, there is from the semantics point of view only read access > possible. Exactly. Showing write access for const variables would look silly. > But try a different look. This is what you see in the debuggers Variable > View when you completely expand b: > ->b const B * const 0x602010 > ->a A * const 0x602030 > i int 0 > > Then you will see that the write access flag is for the whole tree. This may be a limitation of CDT debugging framework or GDB. Neither 0x602010, nor 0x602030 change as a result of the assignment, don't they?
(In reply to comment #7) > (In reply to comment #6) > > In your example b and a are both const with respect to the pointer. > > Therefore, there is from the semantics point of view only read access > > possible. > > Exactly. Showing write access for const variables would look silly. Depends how we define write access :) > > > But try a different look. This is what you see in the debuggers Variable > > View when you completely expand b: > > ->b const B * const 0x602010 > > ->a A * const 0x602030 > > i int 0 > > > > Then you will see that the write access flag is for the whole tree. > > This may be a limitation of CDT debugging framework or GDB. Neither > 0x602010, nor 0x602030 change as a result of the assignment, don't they? There is a misunderstanding. Both addresses do not change. Only 'i' is marked as changed in the Variable View when you step through the code. I thought the picture of a tree would clarify my intentions. But perhaps we should go back to my initial comment. > int array2[100]; > array2[i] = i;// not marked as write occurrence I am mainly interested in this part ([] and * operator). This would be very helpful for my daily work where I want to see where is actual write access to my data. I stumbled about the −> operator when I extended the test cases in VariableReadWriteFlagsTest. If you are not happy about this part I can remove it from the patch.
(In reply to comment #8) > But perhaps we should go back to my initial comment. > > int array2[100]; > > array2[i] = i;// not marked as write occurrence > I am mainly interested in this part ([] and * operator). This would be very > helpful for my daily work where I want to see where is actual write access > to my data. I agree that it would be helpful. > I stumbled about the −> operator when I extended the test cases in > VariableReadWriteFlagsTest. If you are not happy about this part I can > remove it from the patch. The challenge is to come up with a set of rules for what is considered write access and what is not, so that these rules would not lead to silly results like write access for const variables.
(In reply to comment #9) > (In reply to comment #8) > > But perhaps we should go back to my initial comment. > > > int array2[100]; > > > array2[i] = i;// not marked as write occurrence > > I am mainly interested in this part ([] and * operator). This would be very > > helpful for my daily work where I want to see where is actual write access > > to my data. > > I agree that it would be helpful. > > > I stumbled about the −> operator when I extended the test cases in > > VariableReadWriteFlagsTest. If you are not happy about this part I can > > remove it from the patch. > > The challenge is to come up with a set of rules for what is considered write > access and what is not, so that these rules would not lead to silly results > like write access for const variables. But even if we limit the patch to [] and * operator we still could get write access for const variables. int * const x = new int(); *x = 1; I think the main problem here is that for pointers we actually need two markers (as we can set the const attribute differently) but we only have one in the editor (and two different markers would be very confusing).
The current implementation of Mark Occurrences in the editor shows read/write access to a *variable*. But what very often we want to see the read/write access to an *object*. In case of non-pointer type variables this is identical. However, for pointer type variables we ignore the read/write access to the underlying object and expose only the read/write access to the pointer itself. A good coding style is to declare the pointer parameter of a function as const where only the object it points to can be changed. void foo(A * const bar) { bar->x = 1; // marked as *read* access for bar } In this case Mark Occurrences will exhibit only read accesses. Rendering this feature rather pointless [sic]. However, if I use instead a reference as function parameter I get the much different result void foo(A & bar) { bar.x = 1; // marked as *write* access for bar } Both function codes are identical but Mark Occurrences gives me different results! I think we have now the following options: 1) just leave Mark Occurrences as it is and close this bug as WONTFIX => obviously not my preferred option :-) 2) rewrite my patch as suggested in comment #8 and have exceptions for [] and * operator => we would introduce then an inconsistency which would be difficult to comprehend for the user (see example code above) 3) take my patch as is => we would confuse the user why a const variable can have write access (see comment #4 and #10 ) 4) take my patch as is but introduce a preference option for Mark Occurrences where you decide if you want to see read/write access to variables or to objects => Where should we place this preference? How difficult would it be to switch between the two options (i.e. how many mouse clicks would it take)? How would you distinguish the results? How would a user know about this preference key? Aren't there enough options in CDT to choose from? 5) take my patch as is and add some modifications to introduce a new marker which will display read/write access to objects. This marker will be shown in addition to the existing marker for variables => don't we have enough markers already that fill the editor's sidebar? 6) take my patch as is and add some modifications to change the marker text from "Write occurrence of 'bar'" to "Read occurrence of variable 'bar', write occurence of object '*bar'" I would prefer option 6)
(In reply to comment #11) Option 6 is the best in my opinion.
What's the status of this? Alex, do you have plans to implement option (6)?
(In reply to Nathan Ridge from comment #13) > What's the status of this? > > Alex, do you have plans to implement option (6)? I had started working on this in 2013. Unfortunately, it got a little more complicated than expected and then I run out of time. Sorry, but I don't think that I will have enough time to continue my work in the near future.
*** Bug 509382 has been marked as a duplicate of this bug. ***