1

I'll use C as an example language to show what I mean.

struct parent
{
    int x;
    char y;
};
struct child
{
    char y;
    int x;
};

int foo(void * s, type obj_type)
{
    // the casting is done using a "type" variable
    obj_type obj = (obj_type) s;
    return obj->x;
}

int main(int argc, char** argv)
{
    type obj_type = struct parent *;
    struct parent p;
    p.x = 0;

    //returns 0
    foo(&p, obj_type);

    obj_type = struct child *;
    struct child c;
    c.x = 5;

    // returns 5
    foo(&c, obj_type);

    return 0;
}

As you can see, x is placed in different locations in memory for both structs so I can't just have a static offset in memory. Is this possible in C in anyway (some preprocessor magic I couldn't think of)? I assume no, but are there any languages where types can themselves be used as variables? I'd love to explore the implications of type-centered programming

EDIT: as itsme86 pointed out, C# has this ability with the Type class. Also C++ Concepts and Haskell Type class are of interest.

m1cky22
  • 208
  • 1
  • 6
  • I don't think I follow what your asking. Are you wanting `return obj->x;` to return `int`? – J. Allan Aug 02 '16 at 18:18
  • yes. Depending on the type operator though, obj->x might be at the address of obj or it might be an offset of 1 byte away (given the struct setup). What I want is a variable that can be used to identify types rather than values – m1cky22 Aug 02 '16 at 18:19
  • 3
    The feature you're looking for is [type introspection](https://en.wikipedia.org/wiki/Type_introspection). It's available in some object-oriented languages, but not in C (although you can hack it in by adding a `type` member as the first member of all your structs). – user3386109 Aug 02 '16 at 18:20
  • @user3386109 That partially is what I want, but can variables hold these values in any language? For example, C++ supports dynamic_cast but it doesn't look like it allows me to create a new variable whose value is a type – m1cky22 Aug 02 '16 at 18:23
  • Templates in C++? Generics in Java? Higher-level languages like python can hold types like you describe. – ext Aug 02 '16 at 18:26
  • @ext templates can be dynamically substituted for a type at runtime but you cannot instantiate a template type and then change its type from my understanding – m1cky22 Aug 02 '16 at 18:27
  • 1
    C# definitely has this ability. There's a `Type` class that has all sorts of information about whatever type it's referring to. There's also the ability to create a new object of that type at runtime based on that information. – itsme86 Aug 02 '16 at 18:37
  • @itsme86 That's exactly what I was looking for! Awesome! – m1cky22 Aug 02 '16 at 18:41
  • Yes, in some languages types are variables too and can be passed as such. The first that comes to mind is Smalltalk (where everything is an accessible class, also classes themselves, and even the compiler), but also Delphi can do that (at least for classes). And C#. – Rudy Velthuis Aug 02 '16 at 19:12

2 Answers2

2

If you leave type-safety behind you could use offsetof (from stddef.h):

int foo(unsigned char * s, size_t offset)
{
    int* ptr = (int*)(s + offset);
    return *ptr;
}

foo((unsigned char*)&p, offsetof(struct parent, x));

But I would not really recommend it.

ext
  • 2,593
  • 4
  • 32
  • 45
  • That's definitely a way to get some interesting results I was looking for. However, the main reason I'm asking is because I want to see if variable types can contain types as their values, i.e. "type t = int". Is this possible in any language? – m1cky22 Aug 02 '16 at 18:24
0

In Java, you can access type information via the reflections API. Here is an example:

package stackoverflow;

import java.util.Arrays;

public class MyClass {
    public static void main(String[] args) {
        MyClass myInstance = new MyClass(42, "foo");
        Class<MyClass> myClass = MyClass.class;
        System.out.println(myInstance instanceof MyClass);
        System.out.println(myInstance.getClass().equals(myClass));
        System.out.println(myClass.getName());
        System.out.println(Arrays.toString(myClass.getDeclaredFields()));
        System.out.println(Arrays.toString(myClass.getDeclaredMethods()));
    }

    private final int i;
    private final String s;

    public MyClass(int i, String s) {
        this.i = i;
        this.s = s;
    }

    public int getI() {
        return i;
    }

    public String getS() {
        return s;
    }
}

Output:

true
true
stackoverflow.MyClass
[private final int stackoverflow.MyClass.i, private final java.lang.String stackoverflow.MyClass.s]
[public int stackoverflow.MyClass.getI(), public java.lang.String stackoverflow.MyClass.getS(), public static void stackoverflow.MyClass.main(java.lang.String[])]

As you can see, MyClass.class is an object of the generic type java.lang.Class<T>, which provides access to information about the class MyClass. This object can also be retrieved via any instance of the class, see myInstance.getClass(). I included a few examples to show what is accessible. You can also create new instances of a class via its Class object. For more information, you might also want to look into the Javadoc of the java.lang.reflect package.


Please note that this only allows you to access these information. For example, it does not allow you to change the type of an existing instance, which I think is a good thing. However, this seems to be possible in Python:

Can I dynamically convert an instance of one class to another?

Community
  • 1
  • 1
Stefan Dollase
  • 4,530
  • 3
  • 27
  • 51