Dr. Dobb's is part of the Informa Tech Division of Informa PLC

This site is operated by a business or businesses owned by Informa PLC and all copyright resides with them. Informa PLC's registered office is 5 Howick Place, London SW1P 1WG. Registered in England and Wales. Number 8860726.


Channels ▼
RSS

We Have Mail


June 2002/We Have Mail


Letters to the editor may be sent via email to [email protected], or via the postal service to Letters to the Editor, C/C++ Users Journal, 1601 W. 23rd St., Ste 200, Lawrence, KS 66046-2700.


Dear CUJ,

I just got hold of your March 2002 issue and read John F. Hubbard’s article on binary code reuse (“Binary Code Reuse in a Linux Environment”). The use of Flex and Bison were given as an example to demonstrate a general point in solving a problem of launching Unix tools that work on stdin/stdout only. I agree with the general thrust of the argument, but found the article slightly misleading, particularly the assertion that “if you left things as Flex and Bison have set them up, you would require your end users to type:”

cat input_file.txt | BigCompiler"

By default, Flex will read from stdin, which seems like a reasonable default. However, it is a trivial task to make your Flex program read from an input file — an example is even given on the “man” pages for my system, which (slightly reformatted) looks something like this:

#include <stdio.h>
int main( int argc, char* argv[] )
{
    ++argv, --argc;  /* skip over program name */
    if ( argc > 0 )
        yyin = fopen( argv[0], "r" );
    else
        yyin = stdin;
    yylex();
    return 0;
}

The variable yyin is a FILE*. By simply assigning it to something other than stdin, you can read from an input file in about three lines of C code. I find this solution a lot less onerous than the one presented in the article for this particular class of problem.

Regards,

Paul Whitehead

Dear Paul,

Thanks for pointing out a simple, elegant solution to the problem of “how to redirect Flex’s input.” Had I known about this technique, I might have chosen a different example for the article, if for no other reason than to avoid distracting readers who are Flex experts. As it was, I was simply delighted that I could run Flex and Bison effectively, without wasting most of my time!

Even with your technique available, however, I find that the compiler/compiler-driver architecture is a highly recommended approach for many problem domains. GCC uses it, as will many compiler creators, because it allows you to partition a complex problem along classic, easily understandable lines. That is to say, the driver program manages I/O and processes, while the other programs are specialized, encapsulated units of reuse.

Thanks,

John Hubbard


Hi CUJ,

Regarding Joey Roger’s article “Encapsulating Virtual Memory in Windows” in CUJ (January 2002), there is a bug in Listing 1 on page 37.

m_hFile = ::CreateFile(filename, 
                       accessMode,
                       shareMode, NULL,
                       OPEN_EXISTING,
                       FILE_ATTRIBUTE_NORMAL,
                       NULL);
if(m_hFile == NULL)
  return 0;

This return value error checking is buggy. The MSDN documentation for CreateFile says:

    If the function fails, the return value is INVALID_HANDLE_VALUE. To get extended error information, call GetLastError.

The macro INVALID_HANDLE_VALUE is not NULL. For example, if the CreateFile tries to open a file that doesn’t exist, the return value will be 0xffffffff, which is not NULL. The caller of CreateFile should check the return value against INVALID_HANDLE_VALUE.

Regards,

Unnikrishnan.C


Hi CUJ,

I am referring to Bill Gatliff’s article “Implementing Interrupt Service Routines in C++” in the February 2002 issue of CUJ.

In regards to the methods of handling the absence of the this pointer in ISR routines, I think the following snippet of code would illustrate Bill’s point clearer. Consider:

class device_c
{
public:
  device_c()
  // constructor initialize static "this" 
  // counterpart
  { me = this; };
  // non-static Interrupt Service Routine
  void isr();
  // this-like static member
  static device_c *me;
  // static interrupt dispatcher, should be
  // inlined for efficiency
  static interrupt void isr_raw() { me->isr(); }
  // example of non-static data member
  int count;
};

// your interrupt vector table has addresses of
// raw handlers
void (*vector_table[])() =
{
  &device_c::isr_raw,
  // more raw ISRs
};

// storage for static "this"-like member
device_c *device_c::me = NULL; 

void device_c::isr()
{
  // yes, we can do this, we have "this"
  // pointer!!!
  count++;
}

By using this method, you do not need to use the me pointer in your real ISRs and can simply reference your non-static class members in a non-static member ISR function.

Of course, you should not create more than one instance of the device_c class without imposing a rule that the isr routine must only access static members. Therefore, this schema is useful for Singletons, and the only thing it really achieves is it avoids declaring of class members used in the isr function as static (fairly valid reason, I think).

Cheers

Michael Melkonian


Andrew and Barbara,

I have a minor nit-pick on an otherwise excellent article (“C++ Made Easier: Naming Unknown Types,” CUJ, February 2002). The typeof operator is more generally applicable than the article implies. In particular, it is not true that, with typeof, “if f is a function, and we know that f takes a single argument, there is no way to write an expression that represents the type of that argument.” The way out, as usual, is the canonical extra level of indirection, as shown in the attached code (which works with gcc 2.95.2).

The trick is to invoke the helper function std::ptr_fun inside a typeof expression and use the typedefs defined by the resulting function adapter:

typedef typeof( std::ptr_fun( f ) ) fpo_t;
typedef fpo_t::argument_type argtype;
typedef fpo_t::result_type restype;

For example, if f is declared as:

double f( int );

then those typedefs are equivalent to:

typedef std::pointer_to_unary_function
  <int,double> fpo_t;
typedef int argtype;
typedef double restype;

The key observations are:

  • The helper function std::ptr_fun is never called.
  • The function adapter object is never created.
  • The programmer never needs to write out the explicit type of the function adapter.
  • The scope of the definitions of argtype and restype are not restricted to a single function.

This trick works with std::ptr_fun for functions with one or two arguments and can be extended easily to functions with more arguments, class member functions, and doubtless other tricky cases — or at least it would if typeof were standard.

Robert P. Goddard

You are quite right that if we can obtain a name that corresponds to the type of a function — something that typeof could do for us — we can then use a technique such as the one you suggest to obtain the type of the function’s argument. Indeed, this particular technique is widely used in the standard library, std::ptr_fun being just one place where it is used.

But the fact that the technique is already used in the standard library shows that typeof is not necessary in order to solve that particular problem. In fact, I don’t see how typeof would make the solution any easier. All that typeof would do is to give us a way of going from the name of a function to its type; the problem of extracting the argument type from the function type is still solved in the same way, with or without typeof.

For example, suppose we were to make a tiny change to the C++ language definition to allow an expression of the form e.m to denote either a value or a type, depending on whether member m of the class that is the type of e denotes a value or a type. Suppose further that if e.m denotes a type, then the expression e is not evaluated. (It doesn’t need to be evaluated, because all we need is its type.) Then we wouldn’t need typeof to solve the function-argument problem, because we could write something like this:

// This class is already in the standard
// library
template <class Arg, class Res>
struct unary_function {
  typedef Arg argument_type;
  typedef Res result_type;
};

// This function is new
template <class Arg, class Res>
unary_function<Arg, Res> 
  reveal(Res (*f)(Arg)) {
  return unary_function<Arg, Res>();
};

Then with our tiny language change, reveal(f).argument_type would be the type of f’s argument, and reveal(f).result_type would be the type of f’s result.

In this example, as in yours, what really extracts the argument type from the function type is not the use of typeof, nor it is the use of our hypothetical language feature. Rather it is a mechanism that already exists in C++, namely the ability to compute several template parameters from a single template-function argument that happens to incorporate several types. So in that sense, it’s not really typeof that’s solving the problem.

I imagine that this discussion sounds like splitting hairs. Indeed, it probably is. The reason for splitting them is to try to clarify the sense in which we were claiming that typeof doesn’t solve the original problem.

Regards,

Andrew Koenig


Related Reading


More Insights






Currently we allow the following HTML tags in comments:

Single tags

These tags can be used alone and don't need an ending tag.

<br> Defines a single line break

<hr> Defines a horizontal line

Matching tags

These require an ending tag - e.g. <i>italic text</i>

<a> Defines an anchor

<b> Defines bold text

<big> Defines big text

<blockquote> Defines a long quotation

<caption> Defines a table caption

<cite> Defines a citation

<code> Defines computer code text

<em> Defines emphasized text

<fieldset> Defines a border around elements in a form

<h1> This is heading 1

<h2> This is heading 2

<h3> This is heading 3

<h4> This is heading 4

<h5> This is heading 5

<h6> This is heading 6

<i> Defines italic text

<p> Defines a paragraph

<pre> Defines preformatted text

<q> Defines a short quotation

<samp> Defines sample computer code text

<small> Defines small text

<span> Defines a section in a document

<s> Defines strikethrough text

<strike> Defines strikethrough text

<strong> Defines strong text

<sub> Defines subscripted text

<sup> Defines superscripted text

<u> Defines underlined text

Dr. Dobb's encourages readers to engage in spirited, healthy debate, including taking us to task. However, Dr. Dobb's moderates all comments posted to our site, and reserves the right to modify or remove any content that it determines to be derogatory, offensive, inflammatory, vulgar, irrelevant/off-topic, racist or obvious marketing or spam. Dr. Dobb's further reserves the right to disable the profile of any commenter participating in said activities.

 
Disqus Tips To upload an avatar photo, first complete your Disqus profile. | View the list of supported HTML tags you can use to style comments. | Please read our commenting policy.