Web programming in C lang with TCC

A

Angel

You can build what you want from scratch; that is beauty of C in essence
right?

Very true, but sometimes it's more convenient to not have to reinvent
the wheel. :)

C is a wonderful language for all kinds of tasks, but its lack of a
proper string type is one of its major shortcomings IMHO.
 
J

James Kuyper

char *my_match(const char *haystack, const char *pattern);
printf(my_match("hello, world!", ", \\([a-z]*\\)"));

Nice memory leak. ?Note that the only alternatives to a memory leak here
are worse. ?If you have a static buffer you're not thread-safe, for instance.

Thank you.

I guess you were pointing out the possible memory leak in that
proposed design of my_match(), right?

No, it's an actual memory leak in your use of my_match(). Functions that
return pointers to dynamically allocated memory are not, in themselves,
memory leaks. However, a memory leak occurs if those pointers are not
retained for a later call to free(). Here's how to avoid the memory leak:

char * match = my_match("hello, world!", ", \\([a-z]*\\)");
printf(match);
free(match);
There's no necessary to relate Memory Leak with The C Language, right?

The design of the C language makes it substantially more vulnerable to
memory leaks than some other languages. I don't know of any language
that is more vulnerable to such leaks than C, but I suppose that it's
possible.
How about the functions specified in REGEX(3). They have regfree(). Is
it possible to have memory leak when I use these functions?

Of course, if you call regcomp() without following it by a call to
regfree().
For example, is there risk of memory leak in this kind of new design?

char *my_match(const char *haystack,
const char *pattern,
char *result,
size_t pos);

The fact that you pose that question in that form implies that you don't
understand why the code Seebs was talking about produced a memory leak.
Whether or not my_match() can produce a memory leak with that signature
depends upon the semantics of my_match(). If the function returns a
pointer to dynamically allocated memory, and leaves it to the caller of
the program to free() the memory, then whether or not there is a memory
leak depends upon whether or not the caller bothers calling free().
 
J

James Kuyper

You can build what you want from scratch; that is beauty of C in essence
right?

In principle, yes. However, to get maximum benefit from a new string
type, you'd have to create replacements/wrappers for every C standard
library function that takes char* arguments or return char* values. The
replacements/wrappers would take the string arguments or return string
values instead.
 
L

lovecreatesbeauty

char *my_match(const char *haystack, const char *pattern);
printf(my_match("hello, world!", ", \\([a-z]*\\)"));
Nice memory leak. Note that the only alternatives to a memory leak here
are worse. If you have a static buffer you're not thread-safe, for instance.
Thank you.
I guess you were pointing out the possible memory leak in that
proposed design of my_match(), right?

No, it's an actual memory leak in your use of my_match(). Functions that
return pointers to dynamically allocated memory are not, in themselves,
memory leaks. However, a memory leak occurs if those pointers are not
retained for a later call to free(). Here's how to avoid the memory leak:

char * match = my_match("hello, world!", ", \\([a-z]*\\)");
printf(match);
free(match);

Thank you.

Yes, I understand it now.
Of course, if you call regcomp() without following it by a call to
regfree().

Yes, understand it.
The fact that you pose that question in that form implies that you don't
understand why the code Seebs was talking about produced a memory leak.
Whether or not my_match() can produce a memory leak with that signature
depends upon the semantics of my_match(). If the function returns a
pointer to dynamically allocated memory, and leaves it to the caller of
the program to free() the memory, then whether or not there is a memory
leak depends upon whether or not the caller bothers calling free().

I made mistake on that prototyle. I meant this.

int my_match (const char *haystack,
const char *pattern,
char *result,
size_t pos);

The caller will pass variable (allocated, file scope, auto variable i
don't care) as the result argument. Then I don't allocate memory or
use static variables inside my_match().
 
M

Malcolm McLean

On 06/21/2011 03:35 AM, James wrote:

In principle, yes. However, to get maximum benefit from a new string
type, you'd have to create replacements/wrappers for every C standard
library function that takes char* arguments or return char* values. The
replacements/wrappers would take the string arguments or return string
values instead.

Every man and his dog produces a new string type for C.
It's so obvious, by carrying around the length as part of a structure,
we can implement strlen() in O(1) time and strcat(x, y) in O(len(y))
time, y is often much shorter than x.
However the new types never catch on, for a good reason. You've got to
mess about constructing and destroying the strings, then you've got to
integrate with all the code that takes char *s.
 
S

Seebs

I guess you were pointing out the possible memory leak in that
proposed design of my_match(), right?
Yes.

There's no necessary to relate Memory Leak with The C Language, right?

Sort of. Part of the nature of C is that you do your own memory management.
How about the functions specified in REGEX(3). They have regfree(). Is
it possible to have memory leak when I use these functions?

If you are at a level of expertise where you have to ask this question, isn't
it pretty ridiculous for you to be making sweeping claims about the respective
merits of C and other languages?
For example, is there risk of memory leak in this kind of new design?
char *my_match(const char *haystack,
const char *pattern,
char *result,
size_t pos);
If it still has memory leak anyway, is it possible to improve it
further to avoid the memory leak? Can an expert like you implement it
without memory leak? Can you improve it with you expertise and
experience?

That design doesn't tell us enough to know how it would work. Let's ignore
the obvious problem, which is that you've not provided any way to specify
how large the result buffer is.

The minimal case is that you have to allocate storage for a result buffer,
then free that buffer later. You wouldn't have to in a scripting language
that hides memory management.

String manipulations can involve large numbers of allocations and frees.
In C, those are easy to get wrong. In perl/python/ruby/php/et al., those
are impossible to get wrong. It turns out that, if you're doing a lot of
string code, you will always get it written faster and more clearly in
a language designed for it.

Learn to use multiple tools effectively. You're basically arguing that
a really GOOD carpenter should only need a screwdriver, because you can sort
of use a screwdriver to shave things like a plane, and you can bash things
with the handle like a hammer, so really, the screwdriver is the best tool
and we should try to eliminate these other, inferior, tools which can't do
everything.

-s
 
J

James Kuyper

On 06/21/2011 10:08 AM, Malcolm McLean wrote:
....
Every man and his dog produces a new string type for C.

I've been writing C code since 1979, and I've never produce a new string
type. In his eleven years of life, my dog Kiki never produced one
either. Perhaps it was because we were too aware of the disadvantages:
 
M

Michael Press

James Kuyper said:
On 06/21/2011 10:08 AM, Malcolm McLean wrote:
...

I've been writing C code since 1979, and I've never produce a new string
type. In his eleven years of life, my dog Kiki never produced one
either. Perhaps it was because we were too aware of the disadvantages:

:)

This week's award for most literal minded reply.
 
J

James Kuyper

:)

This week's award for most literal minded reply.

Yes, and no. I knew perfectly well that you didn't mean if literally; a
response like that was simply my idea of a joke. However, it's also the
case that I doubt the truth of your claim, even allowing for the
non-literal interpretation you intended. I've never seen C code which
used a new string type. I know how it could be done; a struct containing
a size member and a flexible array member is one obvious approach.
However, it hasn't been done in any code I've ever had to deal with.
 
M

Malcolm McLean

Learn to use multiple tools effectively.  You're basically arguing that
a really GOOD carpenter should only need a screwdriver, because you can sort
of use a screwdriver to shave things like a plane, and you can bash things
with the handle like a hammer, so really, the screwdriver is the best tool
and we should try to eliminate these other, inferior, tools which can't do
everything.
The problem is the analogy doesn't really hold.
Virtually all programs, in whatever language, use for loops, if
statements, assignments, arrays, and print statements. If notation is
different, then it's annoying - you end up typing = for == in C
because in Fortan = is for testing whilst == is for assignment. Matlab
automatically breaks each switch statement. There was a bug in my last
C program - after writing Matlab for several months, I forgot to put
in the break in the C switch. We really need standard conventions for
the things that don't change.

The programs need to be able to talk to each other. I might want to
take a text response from a user, process it, query the database,
generate a 3D image, then create a webpage with the image embedded in
it. The 3d drawing is probably best in OpenGL, the database query in
SQL, the generation of the webpages themselves maybe in Perl. If the
interface conventions are clunky, this becomes difficult.
 
J

James Kuyper

The problem is the analogy doesn't really hold.
Virtually all programs, in whatever language, use for loops, if
statements, assignments, arrays, and print statements.

Perhaps, if you stretch those concepts far enough. In particular, I've
heard that some languages use recursion to achieve the same thing that C
does with loops - thanks to optimization, the generated machine code
might be quite similar, but the source code expresses the idea quite
differently.

Stretching those concepts far enough (for instance, by interpreting
recursion as a "for loop" construct) to cover all programs in all
languages weakens your assertion to the point where it no longer serves
to counter Seebs' analogy. Just because they all do those things in some
form doesn't doesn't mean that they all do them equally well, and
there's a lot of other things that need to be done. Some languages do
some things a LOT better than other languages, and no language does all
things well.
 
K

Keith Thompson

Malcolm McLean said:
The problem is the analogy doesn't really hold.
Virtually all programs, in whatever language, use for loops, if
statements, assignments, arrays, and print statements. If notation is
different, then it's annoying - you end up typing = for == in C
because in Fortan = is for testing whilst == is for assignment. Matlab
automatically breaks each switch statement.
[...]

I think Fortran uses = for both comparison and assignment.
 
B

Ben Bacarisse

That's not my recollection. See below.
[...]

I think Fortran uses = for both comparison and assignment.

Up to (and including) Fortran 77 is was .EQ. but Fortran 90 introduced
== as an alternative for equality.
 
M

Michael Press

James Kuyper said:
Yes, and no. I knew perfectly well that you didn't mean if literally; a
response like that was simply my idea of a joke. However, it's also the
case that I doubt the truth of your claim, even allowing for the
non-literal interpretation you intended. I've never seen C code which
used a new string type. I know how it could be done; a struct containing
a size member and a flexible array member is one obvious approach.
However, it hasn't been done in any code I've ever had to deal with.

Yes, I understood all that, and mean the accolade without reserve.
A deft bit of writing it is.
 
S

Seebs

The problem is the analogy doesn't really hold.

Sure it does!
Virtually all programs, in whatever language, use for loops, if
statements, assignments, arrays, and print statements. If notation is
different, then it's annoying - you end up typing = for == in C
because in Fortan = is for testing whilst == is for assignment. Matlab
automatically breaks each switch statement. There was a bug in my last
C program - after writing Matlab for several months, I forgot to put
in the break in the C switch. We really need standard conventions for
the things that don't change.

Except a lot of those things do change.

I write a fair bit of Ruby. I honestly don't know off the top of my
head whether it has a construct analagous to a C for-loop. You'd never
use one. In C, I might write:
for (i = 0; array; ++i) {
/* do stuff with array */
}
In Ruby, I'd write:
foo.each do |item|
# do stuff with item
end

The idioms really do differ, and they do so for what are often good
reasons relating to the fundamentals of the languages.
The programs need to be able to talk to each other. I might want to
take a text response from a user, process it, query the database,
generate a 3D image, then create a webpage with the image embedded in
it. The 3d drawing is probably best in OpenGL, the database query in
SQL, the generation of the webpages themselves maybe in Perl. If the
interface conventions are clunky, this becomes difficult.

Embedding languages in other languages is a pretty well-understood field.

-s
 
M

Malcolm McLean

Perhaps, if you stretch those concepts far enough. In particular, I've
heard that some languages use recursion to achieve the same thing that C
does with loops - thanks to optimization, the generated machine code
might be quite similar, but the source code expresses the idea quite
differently.

Stretching those concepts far enough (for instance, by interpreting
recursion as a "for loop" construct) to cover all programs in all
languages weakens your assertion to the point where it no longer serves
to counter Seebs' analogy. Just because they all do those things in some
form doesn't doesn't mean that they all do them equally well, and
there's a lot of other things that need to be done. Some languages do
some things a LOT better than other languages, and no language does all
things well.
If you draw a tree, you've got the functional family of programming
language, and the imperative family. Then the imperative family splits
into the procedural and the object-oriented.
However I don't think there are any more significant divisions
(interpreted vs compiled is just an implementation detail). So
basically there's room for three sets of syntactical conventions.
 
J

James Kuyper

If you draw a tree, you've got the functional family of programming
language, and the imperative family. Then the imperative family splits
into the procedural and the object-oriented.
However I don't think there are any more significant divisions
(interpreted vs compiled is just an implementation detail). So
basically there's room for three sets of syntactical conventions.

Yes, it's certainly possible to classify languages, despite their
considerable diversity. The value of the classification process is
suspect, with so many borderline cases, but lets leave that issue aside.
It's still the fact that some languages do some things a lot easier than
others, even within the categories that you've mentioned, much less
across category bodies.

I still think one of the most striking cases of such specialization is
perl's powerful string processing abilities. Like C++, perl has
object-oriented features, but it can also be used in a purely procedural
manner, and perl's superiority to C for processing strings derives
entirely from features that have nothing to do with OO programming.
 
S

Seebs

So basically there's room for three sets of syntactical conventions.

No, there's room for many more, because there are many other distinctions
significant enough to justify not trying to make them look the same.

You have this frustrating tendency to handwave away the substance of
an issue based on a broad overview of it. The high-level view can be
really informative, but it is not the whole of the thing.

-s
 
B

blmblm

If you draw a tree, you've got the functional family of programming
language, and the imperative family. Then the imperative family splits
into the procedural and the object-oriented.
However I don't think there are any more significant divisions
(interpreted vs compiled is just an implementation detail). So
basically there's room for three sets of syntactical conventions.

Um, aren't there languages that are neither functional nor imperative?
Prolog is the example that comes to mind first for me, but there are
probably others.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,579
Members
45,053
Latest member
BrodieSola

Latest Threads

Top