Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

C++ - const issue #190

Open
polidobj opened this issue Mar 21, 2025 · 7 comments
Open

C++ - const issue #190

polidobj opened this issue Mar 21, 2025 · 7 comments
Assignees
Labels
bug Something isn't working

Comments

@polidobj
Copy link

public class B
{
}

public class A
{
  B() member;
  public B! GetB() { return member; }
}

This results in:
'return': cannot convert from 'const B *' to 'B *'

Is this a C++ output issue? Or is this an issue with my fut code?

@pfusik
Copy link
Collaborator

pfusik commented Mar 21, 2025

This is similar to #189. If you return a read-write reference to member, the method must be a mutator:

public B! GetB!() { return member; }

It's an error that is reported by the C++ compiler, but could be checked by fut. Perhaps same fix as for #189 will do.

@pfusik pfusik added the bug Something isn't working label Mar 21, 2025
@pfusik pfusik self-assigned this Mar 21, 2025
@polidobj
Copy link
Author

Ah ok. The function itself doesn't do a mutation. But it still allows someone to do a mutation to a member.

@polidobj
Copy link
Author

It seems now that I need two getter functions. Since if I have a readonly reference to A I can't call that GetB. I need to add this:
public B GetBReadOnly() { return member; }
Is there a better way? It seems like just use read/write all the time instead is easier. Even if in a situation where I'm just reading things.

Here's a sample, that's a bit different than the original above, that isn't allowed that shows what I mean:

public class B
{
}

public class A
{
  Dictionary<string, B>() member;
  public Dictionary<string, B>! GetB!() { return member; }
  public Dictionary<string, B> GetBReadOnly() { return member; }
}

public class C
{
  public void test(A item)
  {
    Dictionary<string, B> var = item.GetB(); // not ok
    Dictionary<string, B> var = item.GetBReadOnly(); // ok
  }
}

@pfusik
Copy link
Collaborator

pfusik commented Mar 21, 2025

Currently there's no other way. Unfortunately, these methods will be identical outside of C++ and C. You can of course remove one with #if.

Are you sure about your design of returning fields by reference? Why not provide modifier methods, e.g.

public SetB!(string key, B value) { member[key] = value; }

?

@polidobj
Copy link
Author

I have done modifier methods for most places that are public API. I mostly come across this with internal things where it was a shortcut to expose the member like that. So I guess I'll have to change the public ones that do that. And either live with two getters for the internal stuff or add methods. Thanks.

@pfusik
Copy link
Collaborator

pfusik commented Mar 21, 2025

If that's within your library code, why not define the fields as internal ? This way you don't need getters.
If you want both methods in your public API, you can add one of the C++ overloads with a conditional (C++ only) native block.

@polidobj
Copy link
Author

I was using internal at first. But then I noticed the friend issue with C++. So until you had fixed that I was trying to avoid using internal. So some of it is leftover from that.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants