Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.c > #387685 > unrolled thread

valgrind leak I can't find

Started byMark Summerfield <mark@qtrac.eu>
First post2024-08-22 08:41 +0000
Last post2024-08-23 09:39 -0400
Articles 20 on this page of 25 — 14 participants

Back to article view | Back to comp.lang.c


Contents

  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 →


#387685 — valgrind leak I can't find

FromMark Summerfield <mark@qtrac.eu>
Date2024-08-22 08:41 +0000
Subjectvalgrind 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]


#387689

FromBen Bacarisse <ben@bsb.me.uk>
Date2024-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]


#387690

FromBart <bc@freeuk.com>
Date2024-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]


#387693

FromThiago Adams <thiago.adams@gmail.com>
Date2024-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]


#387696

FromAnnada Behera <segfault@tilde.green>
Date2024-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]


#387699 — Naming conventions (was Re: valgrind leak I can't find)

FromJanis Papanagnou <janis_papanagnou+ng@hotmail.com>
Date2024-08-22 15:32 +0200
SubjectNaming 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]


#387700 — Re: Naming conventions (was Re: valgrind leak I can't find)

FromThiago Adams <thiago.adams@gmail.com>
Date2024-08-22 11:01 -0300
SubjectRe: 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]


#387719 — Re: Naming conventions (was Re: valgrind leak I can't find)

FromJanis Papanagnou <janis_papanagnou+ng@hotmail.com>
Date2024-08-23 17:10 +0200
SubjectRe: 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]


#387721 — Re: Naming conventions (was Re: valgrind leak I can't find)

FromJames Kuyper <jameskuyper@alumni.caltech.edu>
Date2024-08-23 11:57 -0400
SubjectRe: 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]


#387763 — Re: Naming conventions (was Re: valgrind leak I can't find)

FromJanis Papanagnou <janis_papanagnou+ng@hotmail.com>
Date2024-08-25 18:55 +0200
SubjectRe: 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]


#387788 — Re: Naming conventions (was Re: valgrind leak I can't find)

FromJames Kuyper <jameskuyper@alumni.caltech.edu>
Date2024-08-25 23:47 -0400
SubjectRe: 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]


#387728

FromBlue-Maned_Hawk <bluemanedhawk@invalid.invalid>
Date2024-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]


#387730

Fromscott@slp53.sl.home (Scott Lurndal)
Date2024-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]


#387735

FromKeith Thompson <Keith.S.Thompson+u@gmail.com>
Date2024-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]


#387695

FromIke Naar <ike@sdf.org>
Date2024-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]


#387701

FromKaz Kylheku <643-408-1753@kylheku.com>
Date2024-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]


#387703

FromMark Summerfield <mark@qtrac.eu>
Date2024-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]


#387704

FromKaz Kylheku <643-408-1753@kylheku.com>
Date2024-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]


#387710

FromBart <bc@freeuk.com>
Date2024-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]


#387713

FromMichael S <already5chosen@yahoo.com>
Date2024-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