This is purely out of interest. I searched around a bit, knowing that instances of classes are called objects, but I couldn't find what the correct word is for an instance of a struct in C, C++, C#, etc. Do we even have a word for this?
It is perfectly valid to call it an object even in C.
C99 Standard §3.15:
Para 1:
object
region of data storage in the execution environment, the contents of which can represent
values
In C and C++ word 'object' is much more general. It refers also to structure objects or primitives. From C99 standard:
object
region of data storage in the execution environment, the
contents of which can represent values
In C++ classes and structures are equivalent and types defined with struct are also considered class types. Standard uses expressions like object of class type or object of class X.
Related
The storage layout of C objects is mostly not defined. As far as I know only for struct members and array elements, the layout is defined.
Interestingly for function parameters the C11 standard explicitly mentions that the layout is not defined:
The layout of the storage for parameters is unspecified. (C11 § 6.9.1 P 9)
I was wondering if the standard also explicitly defines that for other objects, e.g., objects with automatic storage duration, the layout is undefined. Is someone aware of this? I couldn't find anything about this in the standard.
What about objects with internal or external linkage?
No, I don't think that there is an explicit mention of the fact that we can't know anything about relative object layout. In fact, the C standard is even more radical than that, you are not even allowed to do comparison with the < operator on two variables that are not elements of the same array, nor may you do arithmetic between pointers to objects that are not part of the same array.
So the whole question of "layout" cannot even be formulate with the terminology that the C standard provides.
This question already has an answer here:
What is the purpose of static keyword in array parameter of function like "char s[static 10]"?
(1 answer)
Closed 8 years ago.
As we know, the keyword static has multiple meanings in C. C99 added the possibility of legally writing
void foo (int arr[static 50])
{
// ...
}
which adds to the confusion, and C++ has static member variables and functions.
This would not be so troublesome if all the uses could be connected in some way, but I find it hard to find that link for some of the cases. Particularly why the static keyword should be used to modify visibility (linkage), or what on earth it's got to do with an array's minimum amount of elements.
So is there a historical reason for the abuse of the static keyword, or is there a secret link under the hood that connects all of its uses?
Adding new keywords to a language breaks backwards compatibility. So static gets used where its use might possibly mean something ( int arr[static 50] vs int arr[auto 50] or int arr[extern 50] ) and cannot syntactically appear in that location based its use in previous versions.
Though in that case adding a not_less_than context sensitive keyword in that position would not break previous code, it would add another keyword (so simple text editors which are keyword aware but not syntax aware would not know whether or not it is a keyword), and break the 'keywords are not context sensitive' simplification made in C.
There is a very simple way of remembering of all 3 C++ meanings of static I'm aware of. static means "pretty much like global variable/function but only available directly in scope of..."
"...this file" if it is in global scope.
"...this function" if it is in a function (including member functions). Note that if you make classes and lambdas in a function, they are still in this scope. Lambda with an empty capture can access static variable of its "parent" function.
"...this class" if it is in a class (including those declared with struct). This case is slightly different as you can access the variable/function through an object or by prefixing, but this is a little like asking the class or its object to provide you access to it, and it in fact can be denied (with private). So the access isn't "direct".
In case of the presented C99 array syntax, this is something completely different and I assume it was there to not introduce new keywords, as others suggest.
static's original meaning in C++ is actually deprecated, replaced with unnamed namespaces. The only way static is actually used in current C++ code is to be non-member.
I think the reasons are different for the different usages that this keyword has. If we take the function scope and file scope use as of classical C for granted (they are at least similar concepts) the first addition off topic is the static in C++ to name a global member of a class.
I guess here the shortcut was just that "static" and "global" seemed to be close enough and early C++ was very careful not to introduce new keywords that would break existing code. So they took an existing one that could not appear in that context.
For the C99 add-on for array parameters things are different, I think, because static is not the only addition, here. You may also have type qualifiers (const and volatile) that qualify the implicit pointer:
void toto1(char str[const 5]);
void toto2(char*const str);
define compatible prototypes. I can only speculate that the choice of the storage class specifier static for the purpose that you mention (minimum length of the array) was seen as a natural extension of that syntax. Also probably it easily proved that this use was compatible with the rest of language, by arguing where a type qualifier may be used to extend the language, a storage class specifier can't do much harm.
A camel is a horse designed by committee.
http://en.wikipedia.org/wiki/Design_by_committee
ADDED:
Committee members involved in the design are conservative, and are more interested in not breaking existing C++ code than the potential elegance of new code.
I read plenty of questions regarding
declaration of functions inside structure?
But I did not get a satisfactory answer.
My question is not about whether functions can be declared inside a structure or not?
Instead, my question is
WHY function can not be declared inside structure?
Well that is the fundamental difference between C and C++ (works in C++). C++ supports classes (and in C++ a struct is a special case of a class), and C does not.
In C you would implement the class as a structure with functions that take a this pointer explicitly, which is essentially what C++ does under the hood. Coupled with a sensible naming convention so you know what functions belong to which classes (again something C++ does under then hood with name-mangling), you get close to object-based if not object-oriented programming. For example:
typedef struct temp
{
int a;
} classTemp ;
void classTemp_GetData( classTemp* pThis )
{
printf( "Enter value of a : " );
scanf( "%d", &(pThis->a) );
}
classTemp T ;
int main()
{
classTemp_GetData( &T );
}
However, as you can see without language support for classes, implementing then can become tiresome.
In C, the functions and data structures are more or less bare; the language gives a minimum of support for combining data structures together, and none at all (directly) for including functions with those data structures.
The purpose of C is to have a language that translates as directly as possible into machine code, more like a portable assembly language than a higher-level language such as C++ (not that C++ is all that high-level). C let's you get very close to the machine, getting into details that most languages abstract away; the down side of this is that you have to get close to the machine in C to use the language to its utmost. It takes a completely different approach to programming from C++, something that the surface similarities between them hide.
Check out here for more info (wonderful discussions there).
P.S.: You can also accomplish the functionality by using function pointers, i.e.
have a pointer to a function (as a variable) inside the struct.
For example:
#include <stdio.h>
struct t {
int a;
void (*fun) (int * a); // <-- function pointers
} ;
void get_a (int * a) {
printf (" input : ");
scanf ("%d", a);
}
int main () {
struct t test;
test.a = 0;
printf ("a (before): %d\n", test.a);
test.fun = get_a;
test.fun(&test.a);
printf ("a (after ): %d\n", test.a);
return 0;
}
WHY function can not be declared inside structure?
Because C standard does not allow to declare function/method inside a structure. C is not object-oriented language.
6.7.2.1 Structure and union specifiers:
A structure or union shall not contain a member with incomplete or function type(hence,
a structure shall not contain an instance of itself, but may contain a pointer to an instance
of itself), except that the last member of a structure with more than one named member
may have incomplete array type; such a structure (and any union containing, possibly
recursively, a member that is such a structure) shall not be a member of a structure or an
element of an array.
I suppose there were and are many reasons, here are several of them:
C programming language was created in 1972, and was influenced by pure assembly language, so struct was supposed as "data-only" element
As soon as C is NOT object oriented language - there is actually no sense to define functions inside "data structure", there are no such entity as constructor/method etc
Functions are directly translated to pure assembly push and call instructions and there are no hidden arguments like this
I guess, because it wouldn't make much sence in C. If you declare a function inside structure, you expect it to be somehow related to that structure, right? Say,
struct A {
int foo;
void hello() {
// smth
}
}
Would you expect hello() to have access to foo at least? Because otherwise hello() only got something like namespace, so to call it we would write A.hello() - it would be a static function, in terms of C++ - not much difference from normal C function.
If hello() has access to foo, there must be a this pointer to implement such access, which in C++ always implicitly passed to functions as first argument.
If a structure function has access to structure variables, it must be different somehow from access that have other functions, again, to add some sence to functions inside structures at all. So we have public, private modificators.
Next. You don't have inheritance in C (but you can simulate it), and this is something that adds lots of sence to declaring functions inside structutes. So here we'd like to add virtual and protected.
Now you can add namespaces and classes, and here you are, invented C++ (well, without templates).
But C++ is object-oriented, and C is not. First, people created C, then they wrote tons of programs, understood some improvements that could be made, and then, following reasonings that I mentioned earlier, they came up with C++. They did not change C instead to separate concepts - C is procedure-oriented, and C++ is object-oriented.
C was designed so that it could be processed with a relatively simple compilation system. To allow function definitions to appear within anything else would have required the compiler to keep track of the context in which the function appeared while processing it. Given that members of a structure, union, or enum declaration do not enter scope until the end of the declaration, there would be nothing that a function declared within a structure could do which a function declared elsewhere could not.
Conceptually, it might have been nice to allow constant declarations within a structure; a constant pointer to a literal function would then be a special case of that (even if the function itself had to be declared elsewhere), but that would have required the C compiler to keep track of more information for each structure member--not just its type and its offset, but also whether it was a constant and, if so, what its value should be. Such a thing would not be difficult in today's compilation environments, but early C compilers were expected to run with orders of magnitude less memory than would be available today.
Given that C has been extended to offer many features which could not very well be handled by a compiler running on a 64K (or smaller) system, it might reasonably be argued that it should no longer be bound by such constraints. Indeed, there are some aspect of C's heritage which I would like to lose, such as the integer-promotion rules which require even new integer types to follow the inconsistent rules for old types, rather than allowing the new types to have explicitly specified behavior [e.g. have a wrap32_t which could be converted to any other integer type without a typecast, but when added to any "non-wrap" integer type of any size would yield a wrap32_t]. Being able to define functions within a struct might be nice, but it would be pretty far down on my list of improvements.
I'm trying to convert a C-Header to pascal, but I'm struggling with the following line:
typedef struct GLFWwindow GLFWwindow;
Since I'm not very good at C I can't even figure out what this statement means. Therefor I'm also unable to translate it.
Is it some kind of anonymous structure or maybe a handle? In the subsequent code it's usually referred to as follows:
typedef void (* GLFWwindowposfun)(GLFWwindow*,int,int);
The thing which confuses me the most is, that the structure is not defined anywhere (it has no member?!). I assume the answer is incredibly simple but nevertheless I hope someone will help me :)
Afaik yes, it is a forward define, making the struct opague, but the final struct should be declared before use in the implementation.
This construct has no direct equivalent in Pascal, best replaced by a single "pointer" or a pointer to an empty record.
The second construct is a procedure type declaration
type
PGLFWWindow = ^GLFWWindow; // pointer types need explicit declaration
// in most modern pascals
TGLFWwindowposfun = Procedure (param1:PGLFFwindowposfun;
param2,param3:integer);cdecl;
Note
prefix "P", "T", delphi style, since all identifiers share one namespace base classes of identifiers are separate by hungarian prefix notation (P=pointer, T=type etc).
The GLFWindow type is better also prefix with T, for consistency.
The integer type is usually the same as C, but e.g. in the default mode FreePascal integer is 16-bit (for TP compatibility). If you use FPC, ctypes.cint is the best fit for C's integer.
Since the default Pascal calling convention is usually not the same as C's on x86, I applied a calling convention modifier cdecl which means "C calling convention".
addendum to be clear, GLFWINDOW would be an empty record (GLWINDOW= record end;), not a pointer to an empty record.
The Python documentation claims that the following does not work on "some platforms or compilers":
int foo(int); // Defined in another translation unit.
struct X { int (*fptr)(int); } x = {&foo};
Specifically, the Python docs say:
We’d like to just assign this to the tp_new slot, but we can’t, for
portability sake, On some platforms or compilers, we can’t statically
initialize a structure member with a function defined in another C
module, so, instead, we’ll assign the tp_new slot in the module
initialization function just before calling PyType_Ready(). --http://docs.python.org/extending/newtypes.html
Is the above standard C89 and/or C99? What compilers specifically cannot handle the above?
That kind of initialization has been permitted since at least C90.
From C90 6.5.7 "Initialization"
All the expressions in an initializer for an object that has static storage duration or in an initializer list for an object that has aggregate or union type shall be constant expressions.
And 6.4 "Constant expressions":
An address constant is a pointer to an lvalue designating an object of static storage duration, or to a function designator; it shall be created explicitly, using the unary & operator...
But it's certainly possible that some implementations might have trouble with the construct - I'd guess that wouldn't be true for modern implementations.
According to n1570 6.6 paragraph 9, the address of a function is an address constant, according to 6.7.9 this means that it can be used to initialize global variables. I am almost certain this is also valid C89.
However,
On sane platforms, the value of a function pointer (or any pointer, other than NULL) is only known at runtime. This means that the initialization of your structure can't take place until runtime. This doesn't always apply to executables but it almost always applies to shared objects such as Python extensions. I recommend reading Ulrich Drepper's essay on the subject (link).
I am not aware of which platforms this is broken on, but if the Python developers mention it, it's almost certainly because one of them got bitten by it. If you're really curious, try looking at an old Python extension and seeing if there's an appropriate message in the commit logs.
Edit: It looks like most Python modules just do the normal thing and initialize type structures statically, e.g., static type obj = { function_ptr ... };. For example, look at the mmap module, which is loaded dynamically.
The example is definitively conforming to C99, and AFAIR also C89.
If some particular (oldish) compiler has a problem with it, I don't think that the proposed solution is the way to go. Don't impose dynamic initialization to platforms that behave well. Instead, special case the weirdos that need special treatment. And try to phase them out as quickly as you may.