1
0
mirror of https://git.savannah.gnu.org/git/gperf.git synced 2025-12-02 21:19:24 +00:00

Portability: Use stack-allocated arrays only if the compiler supports them.

This commit is contained in:
Bruno Haible
2003-04-10 10:26:05 +00:00
parent bfefa088aa
commit f619dea2f5
5 changed files with 61 additions and 6 deletions

View File

@@ -1,5 +1,13 @@
2002-12-12 Bruno Haible <bruno@clisp.org> 2002-12-12 Bruno Haible <bruno@clisp.org>
* src/configure.in: Add test for stack-allocated variable-size arrays.
* src/config.h.in: Regenerated.
* src/search.cc: Include config.h.
(DYNAMIC_ARRAY, FREE_DYNAMIC_ARRAY): New macros.
(Search::find_alpha_inc, Search::count_possible_collisions,
Search::find_asso_values): Use them.
* src/Makefile.in (search.o): Depend on config.h.
* src/search.h (Search::keyword_list_length, Search::max_key_length, * src/search.h (Search::keyword_list_length, Search::max_key_length,
Search::get_max_keysig_size, Search::prepare): Remove declarations. Search::get_max_keysig_size, Search::prepare): Remove declarations.
(Search::prepare): Renamed from Search::preprepare. (Search::prepare): Renamed from Search::preprepare.

View File

@@ -111,7 +111,7 @@ bool-array.o : bool-array.cc $(BOOL_ARRAY_H) $(OPTIONS_H)
$(CXX) $(CXXFLAGS) $(CPPFLAGS) -c $(srcdir)/bool-array.cc $(CXX) $(CXXFLAGS) $(CPPFLAGS) -c $(srcdir)/bool-array.cc
hash-table.o : hash-table.cc $(HASH_TABLE_H) $(OPTIONS_H) hash-table.o : hash-table.cc $(HASH_TABLE_H) $(OPTIONS_H)
$(CXX) $(CXXFLAGS) $(CPPFLAGS) -c $(srcdir)/hash-table.cc $(CXX) $(CXXFLAGS) $(CPPFLAGS) -c $(srcdir)/hash-table.cc
search.o : search.cc $(SEARCH_H) $(OPTIONS_H) $(HASH_TABLE_H) search.o : search.cc $(SEARCH_H) $(OPTIONS_H) $(HASH_TABLE_H) $(CONFIG_H)
$(CXX) $(CXXFLAGS) $(CPPFLAGS) -c $(srcdir)/search.cc $(CXX) $(CXXFLAGS) $(CPPFLAGS) -c $(srcdir)/search.cc
output.o : output.cc $(OUTPUT_H) $(OPTIONS_H) $(VERSION_H) output.o : output.cc $(OUTPUT_H) $(OPTIONS_H) $(VERSION_H)
$(CXX) $(CXXFLAGS) $(CPPFLAGS) -c $(srcdir)/output.cc $(CXX) $(CXXFLAGS) $(CPPFLAGS) -c $(srcdir)/output.cc

View File

@@ -1,5 +1,9 @@
/* config.h.in. Generated automatically from configure.in by autoheader. */ /* config.h.in. Generated automatically from configure.in by autoheader. */
/* Define if the C++ compiler supports stack-allocated variable-size arrays.
*/
#undef HAVE_DYNAMIC_ARRAY
/* Define if the C++ compiler supports "throw ()" declarations. */ /* Define if the C++ compiler supports "throw ()" declarations. */
#undef HAVE_THROW_DECL #undef HAVE_THROW_DECL

View File

@@ -40,6 +40,19 @@ CL_PROG_INSTALL
dnl dnl
dnl checks for compiler characteristics dnl checks for compiler characteristics
dnl dnl
AC_MSG_CHECKING([for stack-allocated variable-size arrays])
AC_CACHE_VAL(gp_cv_cxx_dynamic_array, [
AC_LANG_SAVE()
AC_LANG_CPLUSPLUS()
AC_TRY_COMPILE([int func (int n) { int dynamic_array[n]; }], [],
gp_cv_cxx_dynamic_array=yes, gp_cv_cxx_dynamic_array=no)
AC_LANG_RESTORE()
])
AC_MSG_RESULT($gp_cv_cxx_dynamic_array)
if test $gp_cv_cxx_dynamic_array = yes; then
AC_DEFINE(HAVE_DYNAMIC_ARRAY, 1,
[Define if the C++ compiler supports stack-allocated variable-size arrays.])
fi
dnl dnl
dnl checks for functions and declarations dnl checks for functions and declarations
dnl dnl

View File

@@ -31,9 +31,33 @@
#include <limits.h> /* defines INT_MIN, INT_MAX, UINT_MAX */ #include <limits.h> /* defines INT_MIN, INT_MAX, UINT_MAX */
#include "options.h" #include "options.h"
#include "hash-table.h" #include "hash-table.h"
#include "config.h"
/* ============================== Portability ============================== */
/* Assume ISO C++ 'for' scoping rule. */ /* Assume ISO C++ 'for' scoping rule. */
#define for if (0) ; else for #define for if (0) ; else for
/* Dynamically allocated array with dynamic extent:
Example:
DYNAMIC_ARRAY (my_array, int, n);
...
FREE_DYNAMIC_ARRAY (my_array);
Attention: depending on your implementation my_array is either the array
itself or a pointer to the array! Always use my_array only as expression!
*/
#if HAVE_DYNAMIC_ARRAY
#define DYNAMIC_ARRAY(var,eltype,size) eltype var[size]
#define FREE_DYNAMIC_ARRAY(var)
#else
#define DYNAMIC_ARRAY(var,eltype,size) eltype *var = new eltype[size]
#define FREE_DYNAMIC_ARRAY(var) delete[] var
#endif
/* ================================ Theory ================================= */
/* The most general form of the hash function is /* The most general form of the hash function is
hash (keyword) = sum (asso_values[keyword[i] + alpha_inc[i]] : i in Pos) hash (keyword) = sum (asso_values[keyword[i] + alpha_inc[i]] : i in Pos)
@@ -589,7 +613,7 @@ Search::find_alpha_inc ()
} }
} }
unsigned int indices[nindices]; DYNAMIC_ARRAY (indices, unsigned int, nindices);
{ {
unsigned int j = 0; unsigned int j = 0;
PositionIterator iter = _key_positions.iterator(_max_key_len); PositionIterator iter = _key_positions.iterator(_max_key_len);
@@ -608,8 +632,8 @@ Search::find_alpha_inc ()
/* Perform several rounds of searching for a good alpha increment. /* Perform several rounds of searching for a good alpha increment.
Each round reduces the number of artificial collisions by adding Each round reduces the number of artificial collisions by adding
an increment in a single key position. */ an increment in a single key position. */
unsigned int best[_max_key_len]; DYNAMIC_ARRAY (best, unsigned int, _max_key_len);
unsigned int tryal[_max_key_len]; DYNAMIC_ARRAY (tryal, unsigned int, _max_key_len);
do do
{ {
/* An increment of 1 is not always enough. Try higher increments /* An increment of 1 is not always enough. Try higher increments
@@ -644,6 +668,8 @@ Search::find_alpha_inc ()
} }
} }
while (current_duplicates_count > duplicates_goal); while (current_duplicates_count > duplicates_goal);
FREE_DYNAMIC_ARRAY (tryal);
FREE_DYNAMIC_ARRAY (best);
if (option[DEBUG]) if (option[DEBUG])
{ {
@@ -661,6 +687,7 @@ Search::find_alpha_inc ()
} }
fprintf (stderr, "\n"); fprintf (stderr, "\n");
} }
FREE_DYNAMIC_ARRAY (indices);
} }
_alpha_inc = current; _alpha_inc = current;
@@ -1003,7 +1030,7 @@ Search::count_possible_collisions (EquivalenceClass *partition, unsigned int c)
Return the sum of this expression over all equivalence classes. */ Return the sum of this expression over all equivalence classes. */
unsigned int sum = 0; unsigned int sum = 0;
unsigned int m = _max_selchars_length; unsigned int m = _max_selchars_length;
unsigned int split_cardinalities[m+1]; DYNAMIC_ARRAY (split_cardinalities, unsigned int, m + 1);
for (EquivalenceClass *cls = partition; cls; cls = cls->_next) for (EquivalenceClass *cls = partition; cls; cls = cls->_next)
{ {
for (unsigned int i = 0; i <= m; i++) for (unsigned int i = 0; i <= m; i++)
@@ -1025,6 +1052,7 @@ Search::count_possible_collisions (EquivalenceClass *partition, unsigned int c)
for (unsigned int i = 0; i <= m; i++) for (unsigned int i = 0; i <= m; i++)
sum -= split_cardinalities[i] * split_cardinalities[i]; sum -= split_cardinalities[i] * split_cardinalities[i];
} }
FREE_DYNAMIC_ARRAY (split_cardinalities);
return sum; return sum;
} }
@@ -1231,7 +1259,7 @@ Search::find_asso_values ()
} }
unsigned int iterations = 0; unsigned int iterations = 0;
unsigned int iter[k]; DYNAMIC_ARRAY (iter, unsigned int, k);
for (unsigned int i = 0; i < k; i++) for (unsigned int i = 0; i < k; i++)
iter[i] = 0; iter[i] = 0;
unsigned int ii = (_jump != 0 ? k - 1 : 0); unsigned int ii = (_jump != 0 ? k - 1 : 0);
@@ -1384,6 +1412,8 @@ Search::find_asso_values ()
ii = 0; ii = 0;
} }
} }
FREE_DYNAMIC_ARRAY (iter);
if (option[DEBUG]) if (option[DEBUG])
{ {
fprintf (stderr, "Step %u chose _asso_values[", stepno); fprintf (stderr, "Step %u chose _asso_values[", stepno);