Liste des Groupes | Revenir à cl c |
On 08/04/2025 15:50, David Brown wrote:Yes.On 08/04/2025 13:35, bart wrote:Are they?But this need not be the case. For example this is module A:>
>
--------------------------
#include <stdio.h>
>
typedef struct point {float a; float b;} Point;
>
float dist(Point);
>
int main(void) {
Point p = {3, 4};
printf("%f\n", dist(p));
}
--------------------------
>
And this is module B that defines 'dist':
>
>
--------------------------
#include <math.h>
>
typedef float length;
typedef struct _tag {length x, y;} vector;
>
length dist(vector p) {return sqrt(p.x*p.x + p.y*p.y);}
--------------------------
>
The types involved are somewhat different, but are compatible enough for it to work.
The two types are entirely compatible.
So why does gcc report an error here (the two types are from my example):That is a different situation. In the first case, the types were defined in different translation units - and are compatible. In the second case, they are within the same translation unit, and are not compatible.
typedef struct point {float a; float b;} Point;
typedef float length;
typedef struct _tag {length x, y;} vector;
Point p;
vector v;
p=v;
c.c:14:5: error: incompatible types when assigning to type 'Point' {aka 'struct point'} from type
ector' {aka 'struct _tag'}
14 | p=v;
| ^
The fact that something happens to work does not mean that it is defined behaviour in C."typedef" does not introduce a new type, and struct types in different modules are compatible if they are build from the same compatible field types in the same order.Really? I could have added a dozen extra fields to one (or a pile of incompatible fields to both), and it can still work (especially if I pass the struct by reference).
>>>
However, they could also be different enough (in a more elaborate example) for things to superficially work.
Not in C.
The C language is defined as explained in the standards. If someone writes C code that you think is more complex than necessary, talk to the person writing that code.The preprocessor mechanisms available to work with source code are fairly easy to grasp (but may be complex in practice with multiple nested headers spread over a file system).That's like complaining that integer addition is complex because someone might want to add 26 digit numbers. Stop being silly.You're missing the point: the concept may be simple, but as typically used in C, it is can be much more complex than necessary.
Doing:That is a question of build environment and build instructions. It applies to every programming language. Any time one file refers to another, you need some way to be sure you get exactly the file you intended.
#include "lib.h"
is not enough; there may be a dozen different header locations (from nested includes) that need to be made known to the compiler, so you need to figure them out first!
A program may comprise 100 .c files, but use 37 different headers in mixed, possible nested combinations across those 100 modules. You can't in general tie one .c file to a specific .h file; /that/ would be simpler.This applies to all languages. For example, in Python you do not have separate "interface" and "implementation" files - everything is in one ".py" file. If I have a Python module that says "import my_py_lib", how does Python know where to find "my_py_lib.py" ? How does it know which copy of "my_py_lib.py" to use from the dozen that I have on my computer? The answer is it uses some default rules for the language, some default rules for the implementation, some configuration settings, some flags, some run-time information (equivalent to compile-time information in compiled languages). The exact details are different, but the principle is the same for C and for any other language that can handle more than one file.
So the usual thing applies in C: the language lays down some vague rules, beyond that it's a free-for-all.Apparently, that is the case. It does surprise me a little that you find this difficult - especially since you claim to have written a C compiler but don't seem to have read any of the language standards.
You choose to call that 'being flexible'; I might call it something else.
>You really think that I wouldn't know how to do this if the language provided genuinely simple and well-thought-out and consistent rules?>>
But I had, and do still have, difficulty with how exactly you import and export entities, even ones with linkage.
That sounds very much like a "Bart" problem.
It is /one/ **beeping** page in the standard! It is in /one/ section - section 6.2.2 - titled "Linkages of identifiers". Seven paragraphs, none of which are more than 5 lines long.If you /genuinely/ want to know, and you can't figure it out with a quick google search, reading the page in the standards, or looking at an introduction to C book, then please ask. If you are just trying to claim opportunities to say it's all so difficult and confusing, then don't bother.Ah yes, the Microsoft approach: provide huge amounts of resources, manuals, training courses etc, rather than making something actually simple!
That is why I said it was a bad idea for gcc to have "-fcommon" as the default. It is a real shame that it took so long to change it.Which means a pile of badly written programs.>>
How compilers deal with it have changed.
As a general rule, they have not.
>
But it is true that some compilers have by default supported an extension that was designed to make interoperability with Fortran programs easier
Learn how arrays work in C, and how you can pass around the length of an array between different functions or translation units.And the workaround is...?However if I need to initialise the variable:>
>
extern int table[]; // shared
int table[] = (10, 20, 30)
>
then other modules can't pick up length of the array.
>
Correct.
(Maybe you can appreciate one of many reasons why I normally generate C code for a project as one source file.)I can appreciate that you are the sort of person who, when finding a hole in their sock, would rather chop off their foot than go to the effort of buying a new pair.
I believe the meaning of "extern" in combination with other storage-class specifiers was picked to work with existing old code from before "extern" was added to the language.The C standard gives clear rules here that make sense.What's the rational for allowing both static and extern versions of the same entity in the same file? And if that is allowed, why does the order matter?
(In my compiler I gave up trying to make sense of it, and just ended up allow any combination unless it was clearly wrong.)Again, it is /one/ page in the standard. It is not rocket science. The idea that a person could be smart enough to make their own compiler and not smart enough to understand the rules around linkage in C is utterly laughable. You have are intentionally misunderstanding this so that you can claim C is confusing or badly designed. This is deceitful behaviour.
That does notYou are still wrong.mean they are the /only/ set of rules a language could have that makes sense, but they are not "ad hoc". That would imply that combinations like this could have unpredictable meanings.I don't mean 'ad hoc' to be 'indeterminate'. More like, 'mess', or 'free-for-all'.
Les messages affichés proviennent d'usenet.