Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.c > #387685 > unrolled thread
| Started by | Mark Summerfield <mark@qtrac.eu> |
|---|---|
| First post | 2024-08-22 08:41 +0000 |
| Last post | 2024-08-23 09:39 -0400 |
| Articles | 20 on this page of 25 — 14 participants |
Back to article view | Back to comp.lang.c
valgrind leak I can't find Mark Summerfield <mark@qtrac.eu> - 2024-08-22 08:41 +0000
Re: valgrind leak I can't find Ben Bacarisse <ben@bsb.me.uk> - 2024-08-22 11:40 +0100
Re: valgrind leak I can't find Bart <bc@freeuk.com> - 2024-08-22 12:01 +0100
Re: valgrind leak I can't find Thiago Adams <thiago.adams@gmail.com> - 2024-08-22 08:18 -0300
Re: valgrind leak I can't find Annada Behera <segfault@tilde.green> - 2024-08-22 17:31 +0530
Naming conventions (was Re: valgrind leak I can't find) Janis Papanagnou <janis_papanagnou+ng@hotmail.com> - 2024-08-22 15:32 +0200
Re: Naming conventions (was Re: valgrind leak I can't find) Thiago Adams <thiago.adams@gmail.com> - 2024-08-22 11:01 -0300
Re: Naming conventions (was Re: valgrind leak I can't find) Janis Papanagnou <janis_papanagnou+ng@hotmail.com> - 2024-08-23 17:10 +0200
Re: Naming conventions (was Re: valgrind leak I can't find) James Kuyper <jameskuyper@alumni.caltech.edu> - 2024-08-23 11:57 -0400
Re: Naming conventions (was Re: valgrind leak I can't find) Janis Papanagnou <janis_papanagnou+ng@hotmail.com> - 2024-08-25 18:55 +0200
Re: Naming conventions (was Re: valgrind leak I can't find) James Kuyper <jameskuyper@alumni.caltech.edu> - 2024-08-25 23:47 -0400
Re: valgrind leak I can't find Blue-Maned_Hawk <bluemanedhawk@invalid.invalid> - 2024-08-24 11:47 +0000
Re: valgrind leak I can't find scott@slp53.sl.home (Scott Lurndal) - 2024-08-24 16:48 +0000
Re: valgrind leak I can't find Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2024-08-24 14:04 -0700
Re: valgrind leak I can't find Ike Naar <ike@sdf.org> - 2024-08-22 11:41 +0000
Re: valgrind leak I can't find Kaz Kylheku <643-408-1753@kylheku.com> - 2024-08-22 15:20 +0000
Re: valgrind leak I can't find Mark Summerfield <mark@qtrac.eu> - 2024-08-22 17:44 +0000
Re: valgrind leak I can't find Kaz Kylheku <643-408-1753@kylheku.com> - 2024-08-22 17:50 +0000
Re: valgrind leak I can't find Bart <bc@freeuk.com> - 2024-08-23 12:18 +0100
Re: valgrind leak I can't find Michael S <already5chosen@yahoo.com> - 2024-08-23 16:26 +0300
Re: valgrind leak I can't find James Kuyper <jameskuyper@alumni.caltech.edu> - 2024-08-23 09:39 -0400
Re: valgrind leak I can't find James Kuyper <jameskuyper@alumni.caltech.edu> - 2024-08-23 10:58 -0400
Re: valgrind leak I can't find scott@slp53.sl.home (Scott Lurndal) - 2024-08-23 13:40 +0000
Re: valgrind leak I can't find David Brown <david.brown@hesbynett.no> - 2024-08-23 15:41 +0200
Re: valgrind leak I can't find James Kuyper <jameskuyper@alumni.caltech.edu> - 2024-08-23 09:39 -0400
Page 1 of 2 [1] 2 Next page →
| From | Mark Summerfield <mark@qtrac.eu> |
|---|---|
| Date | 2024-08-22 08:41 +0000 |
| Subject | valgrind leak I can't find |
| Message-ID | <j8idnQlHTPZXZFv7nZ2dnZfqn_GdnZ2d@brightview.co.uk> |
valgrind tells me that I have memory leaks.
Its summary:
valgrind ./cx_test
==18053== Memcheck, a memory error detector
==18053== Copyright (C) 2002-2022, and GNU GPL'd, by Julian Seward et al.
==18053== Using Valgrind-3.19.0 and LibVEX; rerun with -h for copyright info
==18053== Command: ./cx_test
==18053==
OK 788/788
==18053==
==18053== HEAP SUMMARY:
==18053== in use at exit: 841 bytes in 50 blocks
==18053== total heap usage: 2,323,773 allocs, 2,323,723 frees, 65,066,770 bytes allocated
==18053==
==18053== LEAK SUMMARY:
==18053== definitely lost: 841 bytes in 50 blocks
==18053== indirectly lost: 0 bytes in 0 blocks
==18053== possibly lost: 0 bytes in 0 blocks
==18053== still reachable: 0 bytes in 0 blocks
==18053== suppressed: 0 bytes in 0 blocks
==18053== Rerun with --leak-check=full to see details of leaked memory
==18053==
==18053== For lists of detected and suppressed errors, rerun with: -s
==18053== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
The first leak in the detailed report is this:
==18005== 5 bytes in 1 blocks are definitely lost in loss record 1 of 25
==18005== at 0x48407B4: malloc (vg_replace_malloc.c:381)
==18005== by 0x49E38E9: strdup (strdup.c:42)
==18005== by 0x10CAD4: vec_str_tests (vec_str_test.c:77)
==18005== by 0x109346: main (cx_test.c:26)
vec_str_test.c:77 is:
vec_str_insert(&v1, 4, strdup("beta"));
The reason I use strdup() is because my VecStr type takes ownership of
the strings it holds.
This is the type's struct:
typedef struct {
int _size;
int _cap;
char** _values;
} VecStr;
Here is the vec_str_insert() function:
void vec_str_insert(VecStr* vec, int index, char* value) {
assert_notnull(vec);
assert_notnull(value);
if (index == vec->_size) { // add at the end
vec_str_push(vec, value);
return;
}
assert_valid_index(vec, index);
if (vec->_size == vec->_cap)
vec_str_grow(vec);
for (int i = vec->_size; i > index; --i)
vec->_values[i] = vec->_values[i - 1];
vec->_values[index] = value;
vec->_size++;
}
And here is the grow() function it uses:
static void vec_str_grow(VecStr* vec) {
const int BLOCK_SIZE = 1024 * 1024;
int cap =
(vec->_cap < BLOCK_SIZE) ? vec->_cap * 2 : vec->_cap + BLOCK_SIZE;
char** p = realloc(vec->_values, cap * sizeof(char*));
assert_alloc(p);
vec->_values = p;
vec->_cap = cap;
}
I can't see what I've done wrong.
[toc] | [next] | [standalone]
| From | Ben Bacarisse <ben@bsb.me.uk> |
|---|---|
| Date | 2024-08-22 11:40 +0100 |
| Message-ID | <87jzg8263k.fsf@bsb.me.uk> |
| In reply to | #387685 |
Mark Summerfield <mark@qtrac.eu> writes: > valgrind tells me that I have memory leaks. Can you post the whole code? The trouble is, with any bits missing, one just starts speculating about what the code might be even though you may know it's not relevant. The main worry is the I see no calls to free at all, and I don't know what happens to the v1 test vec. Mind you, I may not get time later to look, but I think others will want to see the whole code as well (if that is possible). -- Ben.
[toc] | [prev] | [next] | [standalone]
| From | Bart <bc@freeuk.com> |
|---|---|
| Date | 2024-08-22 12:01 +0100 |
| Message-ID | <va75pv$djqu$1@dont-email.me> |
| In reply to | #387685 |
On 22/08/2024 09:41, Mark Summerfield wrote:
> This is the type's struct:
>
> typedef struct {
> int _size;
> int _cap;
> char** _values;
> } VecStr;
What's with the leading underscores for member names?
It means ending with ->_ later on, which seems pointless extra clutter.
[toc] | [prev] | [next] | [standalone]
| From | Thiago Adams <thiago.adams@gmail.com> |
|---|---|
| Date | 2024-08-22 08:18 -0300 |
| Message-ID | <va76q6$dljb$2@dont-email.me> |
| In reply to | #387690 |
On 22/08/2024 08:01, Bart wrote:
> On 22/08/2024 09:41, Mark Summerfield wrote:
>
>> This is the type's struct:
>>
>> typedef struct {
>> int _size;
>> int _cap;
>> char** _values;
>> } VecStr;
>
> What's with the leading underscores for member names?
>
> It means ending with ->_ later on, which seems pointless extra clutter.
C++ is responsible for this.
C++ made the usage of 'this->' optional when calling member functions.
As a result, when C++ programmers encounter 'i' in the middle of a
function, they might not know where it comes from.
If 'this->' were not optional, 'this->i' would clarify that.
To avoid confusion, many C++ programmers use prefixes like 'm_' that
can't be ignored.
Since many C programmers also work in C++, this pattern can sometimes
influence C code as well.
[toc] | [prev] | [next] | [standalone]
| From | Annada Behera <segfault@tilde.green> |
|---|---|
| Date | 2024-08-22 17:31 +0530 |
| Message-ID | <1c5db75fd1fd3b0e61bd2517a38f2829d0aeee6c.camel@tilde.green> |
| In reply to | #387693 |
On Thu, 2024-08-22 at 08:18 -0300, Thiago Adams wrote:
> On 22/08/2024 08:01, Bart wrote:
> > On 22/08/2024 09:41, Mark Summerfield wrote:
> >
> > > This is the type's struct:
> > >
> > > typedef struct {
> > > int _size;
> > > int _cap;
> > > char** _values;
> > > } VecStr;
> >
> > What's with the leading underscores for member names?
> >
> > It means ending with ->_ later on, which seems pointless extra
> > clutter.
>
>
> C++ is responsible for this.
>
> C++ made the usage of 'this->' optional when calling member
> functions.
>
> As a result, when C++ programmers encounter 'i' in the middle of a
> function, they might not know where it comes from.
>
> If 'this->' were not optional, 'this->i' would clarify that.
>
> To avoid confusion, many C++ programmers use prefixes like 'm_' that
> can't be ignored.
>
> Since many C programmers also work in C++, this pattern can sometimes
> influence C code as well.
Although I think this is stupid thing to do when writing C, the same
convention also exits in Python PEP-8 [1]
_single_leading_underscore: weak “internal use” indicator.
E.g. from M import * does not import objects whose names start with
an underscore.
[1]: https://peps.python.org/pep-0008/#descriptive-naming-styles
[toc] | [prev] | [next] | [standalone]
| From | Janis Papanagnou <janis_papanagnou+ng@hotmail.com> |
|---|---|
| Date | 2024-08-22 15:32 +0200 |
| Subject | Naming conventions (was Re: valgrind leak I can't find) |
| Message-ID | <va7el3$esrp$1@dont-email.me> |
| In reply to | #387696 |
On 22.08.2024 14:01, Annada Behera wrote:
> On Thu, 2024-08-22 at 08:18 -0300, Thiago Adams wrote:
>> On 22/08/2024 08:01, Bart wrote:
>>> On 22/08/2024 09:41, Mark Summerfield wrote:
>>>
>>>> This is the type's struct:
>>>>
>>>> typedef struct {
>>>> int _size;
>>>> int _cap;
>>>> char** _values;
>>>> } VecStr;
>>>
>>> What's with the leading underscores for member names?
A convention. (I.e. one convention amongst dozens.)
>>>
>>> It means ending with ->_ later on, which seems pointless extra
>>> clutter.
>>
>>
>> C++ is responsible for this.
I don't think so. I've seen such conventions in many places, also
very often in C contexts. Even standards use naming conventions.
(This is no valuation. I don't give a valuation. Not yet.)
In C++ I've seen all-caps constant names. (Why? Because C didn't
have constants supported, only CPP elements used as constants,
and that got inherited.) Then '_s' suffixes or 's_' prefixes for
structs. '_t' suffixes for types (typedef entities). 'm_' or '_'
prefixes for class attributes ("member variables"). Conventions
to differentiate function parameters from member variables (for
disambiguity on initialization) or for local function variables.
I've got the feeling that (technical) information that has its
definition already at another (appropriate) place gets merged
into the entities (variables, functions, ...) that (IMO) should
have _semantical_ names, and not something that looks like a C++
name-mangled linker-object-name.
>>
>> C++ made the usage of 'this->' optional when calling member
>> functions.
I don't think this optionality is (per se) a Bad Thing.
But to disambiguate or make intentions clear the use of 'this' is
certainly (IMHO) better than adding technical name components to
semantical names; you already have a language construct you can use
for that.
>>
>> As a result, when C++ programmers encounter 'i' in the middle of a
>> function, they might not know where it comes from.
In the early 1990's we had coding standards that handles such;
use of semantical names instead of 'i', locality principle (don't
declare entities "far away" so you easier see where it's from), and
use of explicit language features (like 'this') to make it obvious.
(Maybe there were yet more suggestions - memories are faint.)
>>
>> If 'this->' were not optional, 'this->i' would clarify that.
Indeed.
Only that it can (also) be perceived as "clutter" (to use a name
that Bart above associated already with the much terser '_').
Most programmers I've met are reluctant to type more characters
than "necessary", and - in the absence of standards/conventions -
they seem to prefer using '_' or 'm_' or some such.
>>
>> To avoid confusion, many C++ programmers use prefixes like 'm_' that
>> can't be ignored.
>>
>> Since many C programmers also work in C++, this pattern can sometimes
>> influence C code as well.
>
> Although I think this is stupid thing to do when writing C, the same
> convention also exits in Python PEP-8 [1]
>
> _single_leading_underscore: weak “internal use” indicator.
> E.g. from M import * does not import objects whose names start with
> an underscore.
>
> [1]: https://peps.python.org/pep-0008/#descriptive-naming-styles
It's a typical document. With valuations "better" (without rationale)
and "ugly!" (which is nothing but a codified opinion).
There's a lot such documents and yet more existing opinions on naming
conventions than options to choose from. I'm sure everyone has one
and it's not really worth to dispute about that. What individuals do
in their private projects' context is their own business and companies
most likely have their conventions documented. - Ah, but there's also
the standards committees...
Janis
[toc] | [prev] | [next] | [standalone]
| From | Thiago Adams <thiago.adams@gmail.com> |
|---|---|
| Date | 2024-08-22 11:01 -0300 |
| Subject | Re: Naming conventions (was Re: valgrind leak I can't find) |
| Message-ID | <va7gb3$f2d0$1@dont-email.me> |
| In reply to | #387699 |
On 22/08/2024 10:32, Janis Papanagnou wrote:
> On 22.08.2024 14:01, Annada Behera wrote:
>> On Thu, 2024-08-22 at 08:18 -0300, Thiago Adams wrote:
>>> On 22/08/2024 08:01, Bart wrote:
>>>> On 22/08/2024 09:41, Mark Summerfield wrote:
>>>>
>>>>> This is the type's struct:
>>>>>
>>>>> typedef struct {
>>>>> int _size;
>>>>> int _cap;
>>>>> char** _values;
>>>>> } VecStr;
>>>>
>>>> What's with the leading underscores for member names?
>
> A convention. (I.e. one convention amongst dozens.)
>
>>>>
>>>> It means ending with ->_ later on, which seems pointless extra
>>>> clutter.
>>>
>>>
>>> C++ is responsible for this.
>
> I don't think so. I've seen such conventions in many places, also
> very often in C contexts. Even standards use naming conventions.
> (This is no valuation. I don't give a valuation. Not yet.)
C++ also made the use of "struct/union/enum" before tags optional.
For example:
struct X x;
In C++, we can write:
X x;
Consequence?
Programmers started using a suffix "C" for classes and "E" for enums.
For example:
CArray array;
EType type;
In C, we have a similar situation where it's sometimes unclear where a
variable comes from.
Consider this code:
void f(int arg1){
i = 2;
}
This can happen with external variables.
For instance:
int i;
void f(int arg1){
i = 2;
}
In this situation, I use a prefix "s_" for the variable, like this:
int s_i;
[toc] | [prev] | [next] | [standalone]
| From | Janis Papanagnou <janis_papanagnou+ng@hotmail.com> |
|---|---|
| Date | 2024-08-23 17:10 +0200 |
| Subject | Re: Naming conventions (was Re: valgrind leak I can't find) |
| Message-ID | <vaa8ol$v263$1@dont-email.me> |
| In reply to | #387700 |
On 22.08.2024 16:01, Thiago Adams wrote:
>
> C++ also made the use of "struct/union/enum" before tags optional.
>
> For example:
>
> struct X x;
>
> In C++, we can write:
>
> X x;
Yes, because it's the "natural" form of a 'Type entity;' declaration.
With a 'class Player;' we write 'Player p;' as we do with an 'int i;'
I don't think it would be a good idea to have to write 'class Player p;'
or 'struct Player p;'. (Mileages may vary.)
In C++ the C's special type 'struct' has been merged in a generalized
form of type, a 'class'.
It may be different for the inherited unions or enums, but anyway...
If I declare a type and give it a name I want to refer to it by that
name in object declarations and not repeat (unnecessary) keywords.
(That's what I'm used to also from other programming languages.)
>
> Consequence?
(C has to struggle with its own inconsistencies since ever. Whether
some C++ language design conventions backfire to C... - well, hard to
tell. I don't think we can clearly deduce or prove any such (social)
effects; at least I cannot.)
>
> Programmers started using a suffix "C" for classes and "E" for enums.
>
> For example:
>
> CArray array;
> EType type;
Yes, I'm well aware of some folks doing so. (That's one point I have
expressed in my previous post. Yet I don't see any advantage in doing
so and haven't heard any substantial rationale for that.)
>
>
> In C, we have a similar situation where it's sometimes unclear where a
> variable comes from.
>
> Consider this code:
>
> void f(int arg1){
> i = 2;
> }
>
> This can happen with external variables.
>
> For instance:
>
> int i;
> void f(int arg1){
> i = 2;
> }
>
>
> In this situation, I use a prefix "s_" for the variable, like this:
>
>
> int s_i;
I'd most likely pass the value through a well defined interface
in such cases; either use (here) the unused function return value,
or add a function argument and pass '&i' to set '*iptr=2' instead
of relying on side-effects accessing global variables, or in more
complex application data cases add a function parameter-object.
Preferences vary, of course, also depending on context.
Janis
[toc] | [prev] | [next] | [standalone]
| From | James Kuyper <jameskuyper@alumni.caltech.edu> |
|---|---|
| Date | 2024-08-23 11:57 -0400 |
| Subject | Re: Naming conventions (was Re: valgrind leak I can't find) |
| Message-ID | <vaac4e$vgm1$1@dont-email.me> |
| In reply to | #387700 |
On 22.08.2024 16:01, Thiago Adams wrote: > > C++ also made the use of "struct/union/enum" before tags optional. > > For example: > > struct X x; > > In C++, we can write: > > X x; > > Consequence? That's possible because C defines separate name spaces of identifiers (not to be confused with C++ namespaces) for labels, tags, each struct or union type, and attributes; all other identifiers are in the ordinary name space. Because of the relevant grammar rules, names in the different spaces can never occur in locations where it is ambiguous as to which name space the identifier is from. Therefore, C allows you do use the same identifier in different name spaces in the same scope with different meanings. For example, identifiers in the tag name space are always prefixed with struct, union or enum, so they can never be confused with names from the ordinary name space. In C++, there are separate name spaces only for macros and labels. All other identifiers are in the same name space, including tags. Class, struct, and union members are not controlled by name spaces, but by scope rules that are different from those in C. That's what allows you to use a tag without a preceding "class", "struct", or "union" keyword. Note: The name space for macros isn't really comparable to the other name spaces I've mentioned, which is why C doesn't have such a name space. Macros are replaced with their expansions during translation phase 3, whereas the other name spaces only become meaningful during translation phase 8. If C were changed to allow use of tags without "struct" or "union" before them, the tag name space would have to be merged into the ordinary name space, and that would break all kinds of legacy code that uses the same identifier as a tag and as an identifier in the ordinary name space. That would be a backwards incompatible change, and the committee tends to avoid such changes. I once spent some time creating an example program that could be compiled in either C or C++, that displayed every construct that had defined behavior in both C and C++, but had incompatibly different behavior in the two languages. Most of the examples involved name spaces. Most of the other differences have at least unspecified behavior in one of the two languages; more often they are syntax errors or constraint violations in the wrong language.
[toc] | [prev] | [next] | [standalone]
| From | Janis Papanagnou <janis_papanagnou+ng@hotmail.com> |
|---|---|
| Date | 2024-08-25 18:55 +0200 |
| Subject | Re: Naming conventions (was Re: valgrind leak I can't find) |
| Message-ID | <vafnlo$20jc0$1@dont-email.me> |
| In reply to | #387721 |
On 23.08.2024 17:57, James Kuyper wrote:
>> [...]
>
> That's possible because C defines separate name spaces of identifiers
> (not to be confused with C++ namespaces) for labels, tags, each struct
> or union type, and attributes; all other identifiers are in the ordinary
> name space. Because of the relevant grammar rules, names in the
> different spaces can never occur in locations where it is ambiguous as
> to which name space the identifier is from. Therefore, C allows you do
> use the same identifier in different name spaces in the same scope with
> different meanings. For example, identifiers in the tag name space are
> always prefixed with struct, union or enum, so they can never be
> confused with names from the ordinary name space.
>
> In C++, there are separate name spaces only for macros and labels. All
> other identifiers are in the same name space, including tags. Class,
> struct, and union members are not controlled by name spaces, but by
> scope rules that are different from those in C. That's what allows you
> to use a tag without a preceding "class", "struct", or "union" keyword.
> Note: The name space for macros isn't really comparable to the other
> name spaces I've mentioned, which is why C doesn't have such a name
> space. Macros are replaced with their expansions during translation
> phase 3, whereas the other name spaces only become meaningful during
> translation phase 8.
>
> If C were changed to allow use of tags without "struct" or "union"
> before them, the tag name space would have to be merged into the
> ordinary name space, and that would break all kinds of legacy code that
> uses the same identifier as a tag and as an identifier in the ordinary
> name space. That would be a backwards incompatible change, and the
> committee tends to avoid such changes.
I recall (when I learned C) that the type definitions confused me.
The clear things were ('typedef'-)definitions like
typedef struct { double re, im; } complex;
But then there were also examples like
typedef struct tnode {
...
struct tnode * right;
} TREENODE, *TREEPTR;
(Both examples taken from an old K&R book.)
In the first case there's no struct name (only the typedef'd one.
In the second case an explicit struct name (necessary for the
type self-reference inside the struct) despite type names being
defined. - Appeared crude to me (and still does).
I don't recall internal name-spaces (as you explain them above)
having been documented and explained. But I may be misremembering.
Janis
> [...]
[toc] | [prev] | [next] | [standalone]
| From | James Kuyper <jameskuyper@alumni.caltech.edu> |
|---|---|
| Date | 2024-08-25 23:47 -0400 |
| Subject | Re: Naming conventions (was Re: valgrind leak I can't find) |
| Message-ID | <vagtt1$2ahdn$3@dont-email.me> |
| In reply to | #387763 |
On 8/25/24 12:55, Janis Papanagnou wrote:
> On 23.08.2024 17:57, James Kuyper wrote:
>>> [...]
>>
>> That's possible because C defines separate name spaces of identifiers
>> (not to be confused with C++ namespaces) for labels, tags, each struct
>> or union type, and attributes; all other identifiers are in the ordinary
>> name space. Because of the relevant grammar rules, names in the
>> different spaces can never occur in locations where it is ambiguous as
>> to which name space the identifier is from. Therefore, C allows you do
>> use the same identifier in different name spaces in the same scope with
>> different meanings. For example, identifiers in the tag name space are
>> always prefixed with struct, union or enum, so they can never be
>> confused with names from the ordinary name space.
>>
>> In C++, there are separate name spaces only for macros and labels. All
>> other identifiers are in the same name space, including tags. Class,
>> struct, and union members are not controlled by name spaces, but by
>> scope rules that are different from those in C. That's what allows you
>> to use a tag without a preceding "class", "struct", or "union" keyword.
>> Note: The name space for macros isn't really comparable to the other
>> name spaces I've mentioned, which is why C doesn't have such a name
>> space. Macros are replaced with their expansions during translation
>> phase 3, whereas the other name spaces only become meaningful during
>> translation phase 8.
>>
>> If C were changed to allow use of tags without "struct" or "union"
>> before them, the tag name space would have to be merged into the
>> ordinary name space, and that would break all kinds of legacy code that
>> uses the same identifier as a tag and as an identifier in the ordinary
>> name space. That would be a backwards incompatible change, and the
>> committee tends to avoid such changes.
>
> I recall (when I learned C) that the type definitions confused me.
>
> The clear things were ('typedef'-)definitions like
>
> typedef struct { double re, im; } complex;
>
> But then there were also examples like
>
> typedef struct tnode {
> ...
> struct tnode * right;
> } TREENODE, *TREEPTR;
>
> (Both examples taken from an old K&R book.)
>
> In the first case there's no struct name (only the typedef'd one.
"A declaration other than a static_assert or attribute declaration shall
declare at least a declarator (other than the parameters of a function
or the members of a structure or union), a tag, or the members of an
enumeration." (6.7p2)
Since the typedef declares a declarator (the typedef name) it don't need
to declare a tag.
> In the second case an explicit struct name (necessary for the
> type self-reference inside the struct) despite type names being
> defined. - Appeared crude to me (and still does).
> I don't recall internal name-spaces (as you explain them above)
> having been documented and explained. But I may be misremembering.
"The C Programming Language", 1st edition makes no mention of name
spaces as such. However, the 2nd Edition was updated to match the latest
draft version of the C89 standard, and explains name spaces in section
A.11.1, which is titled "Lexical Scope". The final C89 standard
described scope in section 3.1.2.1, and name spaces in 3.1.2.3.
[toc] | [prev] | [next] | [standalone]
| From | Blue-Maned_Hawk <bluemanedhawk@invalid.invalid> |
|---|---|
| Date | 2024-08-24 11:47 +0000 |
| Message-ID | <pan$8db48$12dfbf80$ce60889d$2a8f67fc@invalid.invalid> |
| In reply to | #387696 |
Annada Behera wrote: > On Thu, 2024-08-22 at 08:18 -0300, Thiago Adams wrote: > > <snip/> > >> C++ made the usage of 'this->' optional when calling member functions. >> >> As a result, when C++ programmers encounter 'i' in the middle of a >> function, they might not know where it comes from. >> >> If 'this->' were not optional, 'this->i' would clarify that. >> >> To avoid confusion, many C++ programmers use prefixes like 'm_' that >> can't be ignored. >> >> Since many C programmers also work in C++, this pattern can sometimes >> influence C code as well. > > Although I think this is stupid thing to do when writing C, the same > convention also exits in Python PEP-8 [1] > > _single_leading_underscore: weak “internal use” indicator. E.g. from > M import * does not import objects whose names start with an > underscore. > > [1]: https://peps.python.org/pep-0008/#descriptive-naming-styles That's an entirely different convention that is much more common cross- linguistically. I've seen a good bit of C code that's used that for various parts of interfaces that need to be given separate names, but aren't meant to be used directly, such as identifiers constructed in the expansion of a macro. I've personally taken to the habit of naming macros used exclusively to get other macros to work with the name of the macro they're making work prefixed by a number prefixed with an underscore. -- Blue-Maned_Hawk│shortens to Hawk│/blu.mɛin.dʰak/│he/him/his/himself/Mr. blue-maned_hawk.srht.site Made with inadequate loophole sealant!
[toc] | [prev] | [next] | [standalone]
| From | scott@slp53.sl.home (Scott Lurndal) |
|---|---|
| Date | 2024-08-24 16:48 +0000 |
| Message-ID | <I9oyO.540814$ewT2.496768@fx09.iad> |
| In reply to | #387728 |
Blue-Maned_Hawk <bluemanedhawk@invalid.invalid> writes: >Annada Behera wrote: > > >>> If 'this->' were not optional, 'this->i' would clarify that. >>> >>> To avoid confusion, many C++ programmers use prefixes like 'm_' that >>> can't be ignored. Such prefixes for structure (class) members date back to the earliest C compilers, where structure member names were first-class symbols, unqualified by the structure name (any member name could be used with any pointer regardless of pointer type). Thus some means was necessary to disambiguate member names. Remnants of that still exist in POSIX (e.g. the field names for struct stat all start with "st_").
[toc] | [prev] | [next] | [standalone]
| From | Keith Thompson <Keith.S.Thompson+u@gmail.com> |
|---|---|
| Date | 2024-08-24 14:04 -0700 |
| Message-ID | <87y14lfx9a.fsf@nosuchdomain.example.com> |
| In reply to | #387730 |
scott@slp53.sl.home (Scott Lurndal) writes:
> Blue-Maned_Hawk <bluemanedhawk@invalid.invalid> writes:
>>Annada Behera wrote:
>>>> If 'this->' were not optional, 'this->i' would clarify that.
>>>>
>>>> To avoid confusion, many C++ programmers use prefixes like 'm_' that
>>>> can't be ignored.
>
> Such prefixes for structure (class) members date back to the
> earliest C compilers, where structure member names were first-class
> symbols, unqualified by the structure name (any member name could
> be used with any pointer regardless of pointer type). Thus some
> means was necessary to disambiguate member names. Remnants of
> that still exist in POSIX (e.g. the field names for struct stat
> all start with "st_").
And in ISO C, where the members of struct tm have names starting with
"tm_".
--
Keith Thompson (The_Other_Keith) Keith.S.Thompson+u@gmail.com
void Void(void) { Void(); } /* The recursive call of the void */
[toc] | [prev] | [next] | [standalone]
| From | Ike Naar <ike@sdf.org> |
|---|---|
| Date | 2024-08-22 11:41 +0000 |
| Message-ID | <slrnvce8vt.l93.ike@iceland.freeshell.org> |
| In reply to | #387685 |
On 2024-08-22, Mark Summerfield <mark@qtrac.eu> wrote:
> Here is the vec_str_insert() function:
>
> void vec_str_insert(VecStr* vec, int index, char* value) {
> assert_notnull(vec);
> assert_notnull(value);
> if (index == vec->_size) { // add at the end
> vec_str_push(vec, value);
> return;
> }
> assert_valid_index(vec, index);
> if (vec->_size == vec->_cap)
> vec_str_grow(vec);
> for (int i = vec->_size; i > index; --i)
> vec->_values[i] = vec->_values[i - 1];
> vec->_values[index] = value;
> vec->_size++;
> }
Just out of curiosity, why have special code (the vec_str_push part)
for the case index == vec->_size, when the general code (grow, for loop etc.)
would work just fine for that case?
[toc] | [prev] | [next] | [standalone]
| From | Kaz Kylheku <643-408-1753@kylheku.com> |
|---|---|
| Date | 2024-08-22 15:20 +0000 |
| Message-ID | <20240822081732.909@kylheku.com> |
| In reply to | #387685 |
On 2024-08-22, Mark Summerfield <mark@qtrac.eu> wrote:
> The first leak in the detailed report is this:
>
>==18005== 5 bytes in 1 blocks are definitely lost in loss record 1 of 25
>==18005== at 0x48407B4: malloc (vg_replace_malloc.c:381)
>==18005== by 0x49E38E9: strdup (strdup.c:42)
>==18005== by 0x10CAD4: vec_str_tests (vec_str_test.c:77)
>==18005== by 0x109346: main (cx_test.c:26)
>
> vec_str_test.c:77 is:
>
> vec_str_insert(&v1, 4, strdup("beta"));
>
> The reason I use strdup() is because my VecStr type takes ownership of
> the strings it holds.
Does your program free the vector before terminating, including
iterating over the string elements and freeing them individually?
--
TXR Programming Language: http://nongnu.org/txr
Cygnal: Cygwin Native Application Library: http://kylheku.com/cygnal
Mastodon: @Kazinator@mstdn.ca
[toc] | [prev] | [next] | [standalone]
| From | Mark Summerfield <mark@qtrac.eu> |
|---|---|
| Date | 2024-08-22 17:44 +0000 |
| Message-ID | <oKScnQbmXbeW5Fr7nZ2dnZfqn_GdnZ2d@brightview.co.uk> |
| In reply to | #387685 |
Thank you to all who replied.
TL;DR The problem turned out to be a double-free because I had two owning
collections with the same strings. I've now made VecStr and SetStr able to
be owning or nonowning and this valgrind leak has gone.
- I don't want to post the code since it is just for me relearning C.
(I'm creating a tiny collections lib: Vec (of void*), VecStr, VecInt,
SetInt, SetStr.)
- The reason I special cased when index == vec->_size is that I did a
needless premature "optimization": I no longer do this.
- I use underscores for some struct fields. For the collections I provide
functions for their APIs but of course the fields are not private so I use
the underscore in a Python-like way to remind myself they are "private".
- Yes, I free as needed:
typedef struct {
int _size;
int _cap;
char** _values;
bool _owns; // new
} VecStr;
void vec_str_free(VecStr* vec) {
assert_notnull(vec);
vec_str_clear(vec);
free(vec->_values);
vec->_values = NULL;
vec->_cap = 0;
}
void vec_str_clear(VecStr* vec) {
assert_notnull(vec);
if (vec->_owns)
for (int i = 0; i < vec->_size; ++i)
free(vec->_values[i]);
vec->_size = 0;
}
[toc] | [prev] | [next] | [standalone]
| From | Kaz Kylheku <643-408-1753@kylheku.com> |
|---|---|
| Date | 2024-08-22 17:50 +0000 |
| Message-ID | <20240822104819.877@kylheku.com> |
| In reply to | #387703 |
On 2024-08-22, Mark Summerfield <mark@qtrac.eu> wrote: > Thank you to all who replied. > > TL;DR The problem turned out to be a double-free because I had two owning Is it the case that Valgrind reported the double free without stopping the program, but you missed it because you scrolled to the bottom for the leak reports? :) -- TXR Programming Language: http://nongnu.org/txr Cygnal: Cygwin Native Application Library: http://kylheku.com/cygnal Mastodon: @Kazinator@mstdn.ca
[toc] | [prev] | [next] | [standalone]
| From | Bart <bc@freeuk.com> |
|---|---|
| Date | 2024-08-23 12:18 +0100 |
| Message-ID | <va9r6e$t0r0$1@dont-email.me> |
| In reply to | #387703 |
On 23/08/2024 12:03, Stefan Ram wrote: > Mark Summerfield <mark@qtrac.eu> wrote or quoted: >> I don't want to post the code since it is just for me relearning C. > > It's totally your prerogative if you wanna keep your code > on the down-low. No need to spill the beans. > > But just to cut through the fog in your logic, your "since" reasoning > is a bit of a brain-bender: If I'm cranking out some code to sharpen > my C chops, that's no reason to bury it six feet under later on. > >> (I'm creating a tiny collections lib: Vec (of void*), VecStr, VecInt, >> SetInt, SetStr.) > > Yeah, for sure. But we got to wonder if these are really > meat-and-potatoes C problems . . . > > Scope out what C was cooked up for in the first place. Eyeball > those vintage UNIX source files: "find.c", "echo.c", "tar.c", > "ls.c", "zork.c", "tail.c", and all that noise. How many of > those kick off with a container library? > > What gnarly waves are you missing out on in efficient and > idiomatic C programming by thinking, "I'll use my container > library and write C like it's some Silicon Valley startup code!" So, what have you done with the real Stefan Ram?
[toc] | [prev] | [next] | [standalone]
| From | Michael S <already5chosen@yahoo.com> |
|---|---|
| Date | 2024-08-23 16:26 +0300 |
| Message-ID | <20240823162650.000001c6@yahoo.com> |
| In reply to | #387710 |
On Fri, 23 Aug 2024 12:18:38 +0100 Bart <bc@freeuk.com> wrote: > On 23/08/2024 12:03, Stefan Ram wrote: > > Mark Summerfield <mark@qtrac.eu> wrote or quoted: > >> I don't want to post the code since it is just for me relearning > >> C. > > > > It's totally your prerogative if you wanna keep your code > > on the down-low. No need to spill the beans. > > > > But just to cut through the fog in your logic, your "since" > > reasoning is a bit of a brain-bender: If I'm cranking out some code > > to sharpen my C chops, that's no reason to bury it six feet under > > later on. > >> (I'm creating a tiny collections lib: Vec (of void*), VecStr, > >> VecInt, SetInt, SetStr.) > > > > Yeah, for sure. But we got to wonder if these are really > > meat-and-potatoes C problems . . . > > > > Scope out what C was cooked up for in the first place. Eyeball > > those vintage UNIX source files: "find.c", "echo.c", "tar.c", > > "ls.c", "zork.c", "tail.c", and all that noise. How many of > > those kick off with a container library? > > > > What gnarly waves are you missing out on in efficient and > > idiomatic C programming by thinking, "I'll use my container > > library and write C like it's some Silicon Valley startup code!" > > > > So, what have you done with the real Stefan Ram? > It looks like real Stephan Ram hatched out of old restrictive eggshell few months ago. BTW, in order to compare his writing style of old with the new one, I tried to look for his posts on Google Groups. It turned out that I can only see citations. Posts themselves are not archived. Mysterious.
[toc] | [prev] | [next] | [standalone]
Page 1 of 2 [1] 2 Next page →
Back to top | Article view | comp.lang.c
csiph-web