3

I work in Visual Studio 2012. I am just trying to create structure with pointers to same structure:

namespace PLT_1_lab {
    class Program {
        struct tNode {
            string oper;
            int level;
            tNode *left;
            tNode *right;
        }
    }
}

And in lines with * i get error (I have translated VS so it can look a bit different):

Impossible to get address, define size of declare pointer to controlled type ("PLT_1_lab.Program.tNote")

5
  • 1
    The actual error message in english is this: "Cannot take the address of, get the size of, or declare a pointer to a managed type ('PLT_1_lab.Program.tNode')" Commented Jan 6, 2015 at 9:55
  • Why are you trying to use pointers? Or you trying to support C++ code? Commented Jan 6, 2015 at 9:55
  • there is some confusion here you cannot use * in C#. Commented Jan 6, 2015 at 9:55
  • 1
    @Pedro.The.Kid: Uh, yes you can. They're very rarely used, but pointers do exist in C#. Commented Jan 6, 2015 at 9:56
  • As an aside, I'd strongly encourage you to read the .NET naming conventions, getting rid of the t prefix for types. (I'd also encourage you to avoid nested types unless you really need them.) Commented Jan 6, 2015 at 10:01

3 Answers 3

7

In C# you generally use reference types if you need reference mechanics.

A struct is a value type, but a class is a reference type, so changing your struct to a class would do the trick:

class tNode
{
    string oper;
    int level;
    tNode left;
    tNode right;
}

In this context, a null reference is equivalent to C++'s null pointer.

Sign up to request clarification or add additional context in comments.

Comments

5

Matthew's answer is probably the most appropriate way to go, but just to explain why the compiler is complaining...

From the C# 5 specification, section 18.2 (pointer types):

A pointer-type is written as an unmanaged-type or the keyword void, followed by a * token:

pointer-type:
    unmanaged-type   *
    void   *
unmanaged-type:
    type

The type specified before the * in a pointer type is called the referent type of the pointer type. It represents the type of the variable to which a value of the pointer type points.

...

An unmanaged-type is any type that isn’t a reference-type or constructed type, and doesn’t contain reference-type or constructed type fields at any level of nesting. In other words, an unmanaged-type is one of the following:

  • sbyte, byte, short, ushort, int, uint, long, ulong, char, float, double, decimal, or bool.
  • Any enum-type.
  • Any pointer-type.
  • Any user-defined struct-type that is not a constructed type and contains fields of unmanaged-types only.

The intuitive rule for mixing of pointers and references is that referents of references (objects) are permitted to contain pointers, but referents of pointers are not permitted to contain references.

So the problem here is that your tNode struct contains a string value. Without that - and assuming you're in an unsafe context - the code compiles.

Comments

2

No, you can't do that.

The correct way to do this is to use a class instead of a struct.

Now, why is this a problem in the first place?

This is described on MSDN under Pointer types:

A pointer cannot point to a reference or to a struct that contains references, because an object reference can be garbage collected even if a pointer is pointing to it. The garbage collector does not keep track of whether an object is being pointed to by any pointer types.

(my emphasis)

So the problem here isn't the pointer, as such, it is that the struct contains a string.

This struct works:

namespace PLT_1_lab {
    class Program {
        struct tNode {
            // string oper;
            int level;
            tNode *left;
            tNode *right;
        }
    }
}

So another way to fix this would be to replace the pointer to a string with something else, like something that can marshal as a BStr or similar, but all that depends on why you are doing this, instead of just using a class to begin with.

3 Comments

I need to build tree and recursively fill it. And yes, i have only C++ experience and trying to do it in habitual way.
Guess, better to ask question about tree. But at first i will try google lottle more.
Unless you are writing code that will interface with unmanaged code, so that for instance that struct is going to be sent to or received from non-.NET code, I would definitely use a class instead of a struct. If you're currently learning how to program in C# / .NET, I would urge you to disable the unsafe setting on your project and not use it. Again, that's provided you're not going to directly call into unmanaged code.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.